From 86b1a3183aa8785a4721e620245904c7df361fe8 Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Thu, 16 Oct 2025 19:08:07 +0200 Subject: [PATCH 1/3] fix: prevent list item jump on hover in virtual scrolling fix: inconsistent dropdown styling with virtual scroll refactor: deduplicate code --- .../components/selectable-item/styles.scss | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/internal/components/selectable-item/styles.scss b/src/internal/components/selectable-item/styles.scss index a621b07121..b71c4e06a1 100644 --- a/src/internal/components/selectable-item/styles.scss +++ b/src/internal/components/selectable-item/styles.scss @@ -206,6 +206,60 @@ &:first-of-type:not(.selected, .highlighted) { border-block-start-color: awsui.$color-border-dropdown-item-top; } + + // When using virtual scrolling, use box-shadows to mimic changing border + // width and set the actual border to a fixed width to prevent jumping + // behaviour when hovering selectable items + + $virtual-border-offset: calc(#{awsui.$border-item-width} - #{awsui.$border-divider-list-width}); + $virtual-border-offset-double: calc(2 * #{awsui.$border-item-width} - #{awsui.$border-divider-list-width}); + + &.highlighted:not(.selected), + &.selected { + border-width: awsui.$border-divider-list-width; + padding-block: calc(#{styles.$option-padding-vertical} + #{$virtual-border-offset}); + padding-inline: calc(#{styles.$control-padding-horizontal} + #{$virtual-border-offset}); + + &.pad-bottom { + padding-block-end: calc(#{styles.$option-padding-vertical} + #{awsui.$space-xxxs} + #{$virtual-border-offset}); + } + + &.child { + padding-inline-start: calc(#{awsui.$space-xxl} + #{$virtual-border-offset}); + } + + &.parent.interactiveGroups { + padding-block: calc(#{styles.$group-option-padding-vertical} + #{$virtual-border-offset}); + } + } + + &.highlighted:not(.selected) { + box-shadow: inset 0 0 0 $virtual-border-offset awsui.$color-border-dropdown-item-hover; + + &.is-keyboard { + box-shadow: inset 0 0 0 $virtual-border-offset awsui.$color-border-dropdown-item-focused; + } + } + + &.selected { + box-shadow: inset 0 0 0 $virtual-border-offset awsui.$color-border-dropdown-item-selected; + + &.highlighted { + box-shadow: + inset 0 0 0 $virtual-border-offset awsui.$color-border-dropdown-item-selected, + inset 0 0 0 $virtual-border-offset-double awsui.$color-border-dropdown-item-hover; + + &.is-keyboard { + box-shadow: + inset 0 0 0 $virtual-border-offset awsui.$color-border-dropdown-item-selected, + inset 0 0 0 $virtual-border-offset-double awsui.$color-border-dropdown-item-focused; + } + } + } + + &.parent:not(.interactiveGroups) { + border-block-start-color: awsui.$color-border-dropdown-group; + } } } From 681a5f5aa2b64b4edb4c4ee786b00dbf88d85835 Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Mon, 20 Oct 2025 17:50:57 +0200 Subject: [PATCH 2/3] fix: double borders in virtual scroll mode - Each item is shifted up by its index in pixels - The layout strut height is reduced by the number of items to account for the cumulative overlap --- src/select/parts/virtual-list.tsx | 6 +++++- src/select/utils/render-options.tsx | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/select/parts/virtual-list.tsx b/src/select/parts/virtual-list.tsx index 5db64cda75..c6b0e8be62 100644 --- a/src/select/parts/virtual-list.tsx +++ b/src/select/parts/virtual-list.tsx @@ -100,6 +100,10 @@ const VirtualListOpen = forwardRef( withScrollbar, }); + // Adjust totalSize to account for 1px overlap per item (matching the position adjustment in renderOptions) + const overlapAdjustment = filteredOptions.length; + const adjustedTotalSize = totalSize - overlapAdjustment; + return ( {finalOptions} @@ -107,7 +111,7 @@ const VirtualListOpen = forwardRef( aria-hidden="true" key="total-size" className={styles['layout-strut']} - style={{ height: totalSize - stickySize }} + style={{ height: adjustedTotalSize - stickySize }} /> {listBottom ? (
diff --git a/src/select/utils/render-options.tsx b/src/select/utils/render-options.tsx index 614f0d2dd6..580c1a06c9 100644 --- a/src/select/utils/render-options.tsx +++ b/src/select/utils/render-options.tsx @@ -65,11 +65,15 @@ export const renderOptions = ({ const ListItem = useInteractiveGroups ? MultiselectItem : Item; const isSticky = firstOptionSticky && globalIndex === 0; + // Adjust virtual position to create 1px overlap between items (matching non-virtual behavior) + // Subtract globalIndex to shift each item up by 1px per item + const adjustedVirtualPosition = virtualItem ? virtualItem.start - globalIndex : undefined; + return ( Date: Mon, 20 Oct 2025 18:15:30 +0200 Subject: [PATCH 3/3] retrigger checks due to flakiness