Select: Fixes virtualized select showing empty space above selected value (#84544)

* Select: Virtualized select bug replication

* Update with fix

* remove story

* Pin version

* Update

* Update
This commit is contained in:
Torkel Ödegaard 2024-03-15 16:00:58 +01:00 committed by GitHub
parent e93ba13f7a
commit 4dcbf4e5bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 24 additions and 2 deletions

View File

@ -52,6 +52,7 @@
"devDependencies": { "devDependencies": {
"@grafana/tsconfig": "^1.3.0-rc1", "@grafana/tsconfig": "^1.3.0-rc1",
"@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-terser": "0.1.0",
"@testing-library/dom": "9.3.4", "@testing-library/dom": "9.3.4",
"@testing-library/react": "14.2.1", "@testing-library/react": "14.2.1",
"@testing-library/user-event": "14.5.2", "@testing-library/user-event": "14.5.2",

View File

@ -105,6 +105,7 @@ export const Basic: Story<StoryProps> = (args) => {
</> </>
); );
}; };
export const BasicVirtualizedList: Story<StoryProps> = (args) => { export const BasicVirtualizedList: Story<StoryProps> = (args) => {
const [value, setValue] = useState<SelectableValue<string>>(); const [value, setValue] = useState<SelectableValue<string>>();
@ -123,6 +124,7 @@ export const BasicVirtualizedList: Story<StoryProps> = (args) => {
</> </>
); );
}; };
/** /**
* Uses plain values instead of SelectableValue<T> * Uses plain values instead of SelectableValue<T>
*/ */
@ -143,6 +145,7 @@ export const BasicSelectPlainValue: Story<StoryProps> = (args) => {
</> </>
); );
}; };
/** /**
* Uses plain values instead of SelectableValue<T> * Uses plain values instead of SelectableValue<T>
*/ */

View File

@ -50,7 +50,7 @@ export const VirtualizedSelectMenu = ({ children, maxHeight, options, getValue }
const [value] = getValue(); const [value] = getValue();
const valueIndex = value ? options.findIndex((option: SelectableValue<unknown>) => option.value === value.value) : 0; const valueIndex = value ? options.findIndex((option: SelectableValue<unknown>) => option.value === value.value) : 0;
const initialOffset = valueIndex * VIRTUAL_LIST_ITEM_HEIGHT; const valueYOffset = valueIndex * VIRTUAL_LIST_ITEM_HEIGHT;
if (!Array.isArray(children)) { if (!Array.isArray(children)) {
return null; return null;
@ -60,6 +60,9 @@ export const VirtualizedSelectMenu = ({ children, maxHeight, options, getValue }
const widthEstimate = longestOption * VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER; const widthEstimate = longestOption * VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER;
const heightEstimate = Math.min(options.length * VIRTUAL_LIST_ITEM_HEIGHT, maxHeight); const heightEstimate = Math.min(options.length * VIRTUAL_LIST_ITEM_HEIGHT, maxHeight);
// Try to scroll to keep current value in the middle
const scrollOffset = Math.max(0, valueYOffset - heightEstimate / 2);
return ( return (
<List <List
className={styles.menu} className={styles.menu}
@ -68,7 +71,7 @@ export const VirtualizedSelectMenu = ({ children, maxHeight, options, getValue }
aria-label="Select options menu" aria-label="Select options menu"
itemCount={children.length} itemCount={children.length}
itemSize={VIRTUAL_LIST_ITEM_HEIGHT} itemSize={VIRTUAL_LIST_ITEM_HEIGHT}
initialScrollOffset={initialOffset} initialScrollOffset={scrollOffset}
> >
{({ index, style }) => <div style={{ ...style, overflow: 'hidden' }}>{children[index]}</div>} {({ index, style }) => <div style={{ ...style, overflow: 'hidden' }}>{children[index]}</div>}
</List> </List>

View File

@ -4027,6 +4027,7 @@ __metadata:
"@grafana/tsconfig": "npm:^1.3.0-rc1" "@grafana/tsconfig": "npm:^1.3.0-rc1"
"@grafana/ui": "npm:11.0.0-pre" "@grafana/ui": "npm:11.0.0-pre"
"@rollup/plugin-node-resolve": "npm:15.2.3" "@rollup/plugin-node-resolve": "npm:15.2.3"
"@rollup/plugin-terser": "npm:0.1.0"
"@testing-library/dom": "npm:9.3.4" "@testing-library/dom": "npm:9.3.4"
"@testing-library/react": "npm:14.2.1" "@testing-library/react": "npm:14.2.1"
"@testing-library/user-event": "npm:14.5.2" "@testing-library/user-event": "npm:14.5.2"
@ -7024,6 +7025,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/plugin-terser@npm:0.1.0":
version: 0.1.0
resolution: "@rollup/plugin-terser@npm:0.1.0"
dependencies:
terser: "npm:^5.15.1"
peerDependencies:
rollup: ^2.x || ^3.x
peerDependenciesMeta:
rollup:
optional: true
checksum: 10/e8abed2bc9f91d2aa54819fd26e98333596b97153bb1d636fe2396db258ea580cc6c88f9e28ea2f69a20fa4e7dca33d0a9f235cd21986f4b633484757b0f31d2
languageName: node
linkType: hard
"@rollup/pluginutils@npm:^3.0.9": "@rollup/pluginutils@npm:^3.0.9":
version: 3.1.0 version: 3.1.0
resolution: "@rollup/pluginutils@npm:3.1.0" resolution: "@rollup/pluginutils@npm:3.1.0"