UNPKG

@grafana/ui

Version:
1 lines 6.58 kB
{"version":3,"file":"useComboboxFloat.mjs","sources":["../../../../src/components/Combobox/useComboboxFloat.ts"],"sourcesContent":["import { autoUpdate, autoPlacement, size, useFloating } from '@floating-ui/react';\nimport { useMemo, useRef, useState } from 'react';\n\nimport { measureText } from '../../utils/measureText';\n\nimport {\n MENU_ITEM_FONT_SIZE,\n MENU_ITEM_FONT_WEIGHT,\n MENU_ITEM_PADDING,\n MENU_OPTION_HEIGHT,\n POPOVER_MAX_HEIGHT,\n} from './getComboboxStyles';\nimport { ComboboxOption } from './types';\n\n// Only consider the first n items when calculating the width of the popover.\nconst WIDTH_CALCULATION_LIMIT_ITEMS = 100_000;\n\n// Clearance around the popover to prevent it from being too close to the edge of the viewport\nconst POPOVER_PADDING = 16;\n\nconst SCROLL_CONTAINER_PADDING = 8;\n\nexport const useComboboxFloat = (items: Array<ComboboxOption<string | number>>, isOpen: boolean) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const [popoverMaxSize, setPopoverMaxSize] = useState<{ width: number; height: number }>({\n width: 0,\n height: 0,\n }); // set initial values to prevent infinite size, briefly removing the list virtualization\n\n const scrollbarWidth = useMemo(() => getScrollbarWidth(), []);\n\n // the order of middleware is important!\n const middleware = [\n autoPlacement({\n // see https://floating-ui.com/docs/autoplacement\n allowedPlacements: ['bottom-start', 'bottom-end', 'top-start', 'top-end'],\n boundary: document.body,\n crossAxis: true,\n }),\n size({\n apply({ availableWidth, availableHeight }) {\n const preferredMaxWidth = availableWidth - POPOVER_PADDING;\n const preferredMaxHeight = availableHeight - POPOVER_PADDING;\n\n const width = Math.max(preferredMaxWidth, 0);\n const height = Math.min(Math.max(preferredMaxHeight, MENU_OPTION_HEIGHT * 6), POPOVER_MAX_HEIGHT);\n\n setPopoverMaxSize({ width, height });\n },\n }),\n ];\n const elements = { reference: inputRef.current, floating: floatingRef.current };\n const { floatingStyles } = useFloating({\n strategy: 'fixed',\n open: isOpen,\n placement: 'bottom-start',\n middleware,\n elements,\n whileElementsMounted: autoUpdate,\n });\n\n const longestItemWidth = useMemo(() => {\n let longestItem = '';\n const itemsToLookAt = Math.min(items.length, WIDTH_CALCULATION_LIMIT_ITEMS);\n\n for (let i = 0; i < itemsToLookAt; i++) {\n const itemLabel = items[i].label ?? items[i].value.toString();\n longestItem = itemLabel.length > longestItem.length ? itemLabel : longestItem;\n }\n\n const size = measureText(longestItem, MENU_ITEM_FONT_SIZE, MENU_ITEM_FONT_WEIGHT).width;\n\n return size + SCROLL_CONTAINER_PADDING + MENU_ITEM_PADDING * 2 + scrollbarWidth;\n }, [items, scrollbarWidth]);\n\n const floatStyles = {\n ...floatingStyles,\n width: longestItemWidth,\n maxWidth: popoverMaxSize.width,\n minWidth: inputRef.current?.offsetWidth,\n\n maxHeight: popoverMaxSize.height,\n };\n\n return { inputRef, floatingRef, scrollRef, floatStyles };\n};\n\n// Creates a temporary div with a scrolling inner div to calculate the width of the scrollbar\nfunction getScrollbarWidth(): number {\n const outer = document.createElement('div');\n outer.style.visibility = 'hidden';\n outer.style.overflow = 'scroll';\n document.body.appendChild(outer);\n\n const inner = document.createElement('div');\n outer.appendChild(inner);\n\n const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;\n\n outer.parentNode?.removeChild(outer);\n\n return scrollbarWidth;\n}\n"],"names":["_a","size"],"mappings":"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"}