Vega carousel starts to behave anchored when item is removed, selection strategy is pinned and pinned focus offset is start

:warning: Before you continue


Before submitting a bug report, please review our troubleshooting documentation at Troubleshoot Issues | Vega Troubleshooting

If you still want to file a bug report, please make sure to fill in all the details below and provide the necessary information.

NOTE: PLEASE ONLY REPORT A SINGLE BUG USING THIS TEMPLATE.
If you’re experiencing multiple issues, please file a separate report for each.


:backhand_index_pointing_right: Bug Description


1. Summary

Pinned focus offset is start.Selection strategy is pinned.Carousel is Horizontal.When an item is removed and rendered count was greater than or equal to data set length, when user interacts with it , it behaves as using selection strategy anchored.In certain situations, the carousel will dirft and trapSelectionStrategy is unable to hold focus on the right edge of carousel, though I have not been able to pin point when exactly.

App Name:
App Link on Amazon Appstore (found through Developer Console → Actions column in App List → View on Amazon.com):

Bug Severity
Select one that applies

  • Impacts operation of app
  • Blocks current development
  • Improvement suggestion
  • Issue with documentation (If selected, please share the doc link and describe the issue)
  • Other

2. Steps to Reproduce

  1. [List the steps for reproducing the bug]
  2. [Any specific component or method call in React Native triggering the issue]

3. Observed Behavior

Explain what actually happened, noting any discrepancies or malfunctions.

The scroll behaves as selection strategy anchored

4. Expected Behavior

Describe what you expected the SDK to do under normal operation.

the scroll should behave as pinned

4.a Possible Root Cause & Temporary Workaround

Fill out anything you have tried. If you don’t know, N/A is acceptable

remounting carousel and requesting focus on last focused item is a workaround

5. Logs or crash report

(Please make sure to provide relevant logs as attachment)

For crash issues, please refer this guide for faster troubleshooting: Detect Where the App Crash Originates | Design and Develop Vega Apps

  • App/Device Logs

  • Crash Logs

  • Crash Report

  • For issues with Vega Studio Extension, please share log files from below folders:
    For v0.22+:

    ~/.vscode/extensions/amazon.vega-extension-<version>/ExtensionLogs
    ~/.vscode/extensions/amazon.vega-ui-extension-<version>/ExtensionLogs
    

    For v0.21 and earlier:

     ~/.vscode/extensions/amazon.kepler-extension-<version>/ExtensionLogs
     ~/.vscode/extensions/amazon.kepler-ui-extension-<version>/ExtensionLogs
    

6. Environment

Please fill out the fields related to your bug below:

  • SDK Version: Active SDK Version: 0.23.8128

    Vega CLI Version: 1.2.22

  • App State: Foreground

  • OS Information: Please ssh into the device via vega exec vda shell (or kepler exec vda shell for v0.21 and earlier) and copy the output from cat /etc/os-release into the answer section below. Note, if you don’t have a simulator running or device attached, the command will respond with vda: no devices/emulators found

    <!-- Answer here if applicable --> 
    

7. Example Code Snippet / Screenshots / Screengrabs

Include any relevant code or component setup in React Native that can help reproduce the bug.

import { Carousel } from '@amazon-devices/vega-carousel'
import { useMemo, useState } from 'react'
import { Pressable, Text, TVFocusGuideView, View } from 'react-native'

/**
 * Minimal reproduction for @amazon-devices/vega-carousel
 * ------------------------------------------------------
 * BUG: With selectionStrategy="pinned" (pinnedSelectedItemOffset="start"), if
 * the ENTIRE list is mounted (itemCount <= renderedItemsCount, i.e. no
 * virtualization) and an item is then removed from the data, the carousel
 * starts to beheve as anchored selection strategy
 * (it behaves as if "anchored" instead of "pinned").
 *
 * When the list is large enough to virtualize (itemCount > renderedItemsCount)
 * the same removal recomputes the pinned offset correctly.
 *
 * REPRO STEPS:
 *  1. Launch. 6 items, renderedItemsCount=10 -> the whole list is mounted
 *     (no virtualization).
 *  2. Move focus RIGHT to a later item (e.g. item 4 or 5) so the row scrolls
 *     and the selected item is pinned to the start (left) edge.
 *  3. Press the "Remove item 1" button (removes the 2nd item from the data).
 *  
 *
 * To confirm it's the no-virtualization path: raise ITEM_COUNT above
 * renderedItemsCount (e.g. 14) and repeat
 */

const RENDERED_ITEMS_COUNT = 10
// itemCount (6) <= RENDERED_ITEMS_COUNT (10) => no virtualization => drift.
// Raise to 14 (> 10) to see the bug NOT happen (virtualized path).
const ITEM_COUNT = 6
const ITEM_WIDTH = 330

type Item = { id: string }
const makeItems = (n: number): Item[] =>
  Array.from({ length: n }, (_, i) => ({ id: `item-${i}` }))

export default function VegaCarouselPinnedRemovalRepro() {
  const [items, setItems] = useState<Item[]>(() => makeItems(ITEM_COUNT))

  const dataAdapter = useMemo(
    () => ({
      getItem: (index: number) => items[index],
      getItemCount: () => items.length,
      getItemKey: ({ item }: { item: Item; index: number }) => item.id,
      notifyDataError: () => false,
    }),
    [items],
  )

  const removeSecondItem = () =>
    setItems((prev) => prev.filter((_, i) => i !== 1))

  const renderItem = ({ item }: { item: Item; index: number }) => (
    <Pressable
      focusable
      style={({ focused }: { focused?: boolean }) => ({
        width: ITEM_WIDTH,
        height: 150,
        borderRadius: 13,
        borderWidth: 5,
        borderColor: focused ? 'red' : 'green',
        backgroundColor: 'black',
        alignItems: 'center',
        justifyContent: 'center',
      })}
    >
      <Text style={{ color: 'white', fontSize: 32 }}>{item.id}</Text>
    </Pressable>
  )

  return (
    <TVFocusGuideView autoFocus style={{ flex: 1, padding: 60 }}>
      <Text style={{ color: 'white', fontSize: 28, marginBottom: 24 }}>
        press Remove.List starts to behave as anchored
      </Text>

      <Pressable
        focusable
        hasTVPreferredFocus
        onPress={removeSecondItem}
        style={({ focused }: { focused?: boolean }) => ({
          alignSelf: 'flex-start',
          paddingHorizontal: 30,
          paddingVertical: 17,
          borderRadius: 12,
          backgroundColor: focused ? '#3a7afe' : '#444',
          marginBottom: 35,
        })}
      >
        <Text style={{ color: 'white', fontSize: 24 }}>Remove item 1</Text>
      </Pressable>

      <View style={{ height: 150 }}>
        <Carousel
          orientation="horizontal"
          dataAdapter={dataAdapter}
          renderItem={renderItem as never}
          renderedItemsCount={RENDERED_ITEMS_COUNT}
          itemStyle={{ itemPadding: 16 }}
          trapSelectionOnOrientation
          selectionStrategy="pinned"
          pinnedSelectedItemOffset="start"
          hideItemsBeforeSelection={false}
        />
      </View>
    </TVFocusGuideView>
  )
}


:backhand_index_pointing_right: Playback Issues


If this is a playback issue, please provide your content URL, any pre-conditions (like geo-location), and let us know if it’s x86 or arm7.


<!-- Describe your playback issue if applicable -->

Please share the following details in addition:_

  • Player SDK: [Bitmovin, Shaka, ...]
  • Player SDK Version: [e.g. 1.23]
    • Audio Codecs: [AAC, ...]
    • Video Codecs: [h.264, mp4]
    • Manifest Types: [m3u8, dash, etc ..]

Q: If applicable, please provide your media/content url
If this is created dynamically, tokenized, etc please provide a way for us to access it

[N/A or Content / Media Url for testing]

Q: Are there any special headers required to reproduce the issue you are facing?

[N/A or Insert Headers]

Additionally please provide the following if possible
Provide Screenshots / Screengrabs / Logs. Please include as much information as you can that will help debug.

<!-- Answer here if applicable --> 

:backhand_index_pointing_right: Additional Context


Any Additional Context you would like to provide?
Add any other relevant information, such as recent updates to the SDK, dependencies, or device OS that may affect the bug.

it behaves fine if list is large enough that virtualization can happen.Similar issue is present in vertical carousels.in some situations, the carousel drifts to left in navigableScrollAreaMargin space and trapSelectionOrientation may not be able to trap focus.

vega carousel (0.2.0), sdk 0.23

Hi @Rishabh_Ritweek,

Thank you for the detailed bug report on the carousel selection strategy issue — the reproduction code and clear description of the conditions (non-virtualized list with selectionStrategy="pinned" and pinnedSelectedItemOffset="start" reverting to anchored behavior after item removal) are very helpful.

Our team is investigating this issue and will provide an update as soon as we have more information.

Thanks for helping us improve the Vega platform.

Warm regards,
Aishwarya

Thank you for your response.on simulator, I also get SIGABART crash @Aishwarya , have not seen the crash on a real tv device.I do not have a fixed pattern, how and when that crash occurs.. If I am able to pin point the pattern, I will provide an update.