diff --git a/webapp/common-react/@dbeaver/ui-kit/src/Menu/MenuField.tsx b/webapp/common-react/@dbeaver/ui-kit/src/Menu/MenuField.tsx index 5dd3ea52e0..08bdbc9081 100644 --- a/webapp/common-react/@dbeaver/ui-kit/src/Menu/MenuField.tsx +++ b/webapp/common-react/@dbeaver/ui-kit/src/Menu/MenuField.tsx @@ -7,7 +7,7 @@ */ import clsx from 'clsx'; -import { MenuProvider, Menu, MenuButton, MenuItem, MenuButtonArrow, useMenuStore, useStoreState, type MenuProps } from './Menu.js'; +import { MenuProvider, Menu, MenuButton, MenuButtonArrow, useMenuStore, useStoreState, type MenuProps } from './Menu.js'; import './MenuField.css'; import { useLayoutEffect } from 'react'; @@ -23,25 +23,11 @@ export interface MenuFieldProps> { /** Options array - can be MenuItemData objects or arbitrary objects */ items: ItemType[]; - /** - * Function to extract value from items - * Example: (item) => item.id - */ - itemValue?: PropertyGetter; - /** * Function to extract label or render content from items * Example: (item) => item.firstName + ' ' + item.lastName */ - itemRender?: PropertyGetter; - - /** - * Function to extract disabled state - * Example: (item) => !item.isActive - */ - itemDisabled?: PropertyGetter; - - onChange?: (value: T) => void; + itemRender: PropertyGetter; onSwitch?: (open: boolean) => void; @@ -75,22 +61,10 @@ export interface MenuFieldProps> { id?: string; } -// Utility function to get value by it's key or using getter function -function getValueByPath(item: Item, getter: PropertyGetter | undefined, defaultGetter: (item: Item) => Value): Value { - return getter ? getter(item) : defaultGetter(item); -} - -function isNonNullObject(value: unknown): value is Record { - return typeof value === 'object' && value !== null; -} - export function MenuField>({ items, - onChange, - itemValue, onSwitch, itemRender, - itemDisabled, getAnchorRect, label, noItemsPlaceholder = 'No items', @@ -104,21 +78,6 @@ export function MenuField>({ }: MenuFieldProps): React.ReactElement { const storeState = useStoreState(store); - const getItemValue = (item: ItemType): T => - getValueByPath(item, itemValue, i => - isNonNullObject(i) && 'value' in i ? (i as unknown as MenuItemData).value : (i as unknown as T), - ); - - const renderItem = (item: ItemType): React.ReactNode => - getValueByPath(item, itemRender, i => - isNonNullObject(i) && 'label' in i ? (i as unknown as MenuItemData).label : String(i), - ); - - const isItemDisabled = (item: ItemType): boolean => - getValueByPath(item, itemDisabled, i => - isNonNullObject(i) && 'disabled' in i ? Boolean((i as unknown as MenuItemData).disabled) : false, - ); - const isOpen = storeState?.open ?? false; useLayoutEffect(() => { @@ -134,15 +93,7 @@ export function MenuField>({ {description && {description}} - {items.length === 0 ? ( -
{noItemsPlaceholder}
- ) : ( - items.map(item => ( - onChange?.(getItemValue(item))}> - {renderItem(item)} - - )) - )} + {items.length === 0 ?
{noItemsPlaceholder}
: items.map(itemRender)}
diff --git a/webapp/packages/core-blocks/src/Menu/AriaKit/MenuAriaKit.tsx b/webapp/packages/core-blocks/src/Menu/AriaKit/MenuAriaKit.tsx index c25c066028..866b67858b 100644 --- a/webapp/packages/core-blocks/src/Menu/AriaKit/MenuAriaKit.tsx +++ b/webapp/packages/core-blocks/src/Menu/AriaKit/MenuAriaKit.tsx @@ -20,13 +20,13 @@ import { ErrorBoundary } from '../../ErrorBoundary.js'; import type { IContextMenuPosition } from '../useContextMenuPosition.js'; import './MenuAriaKit.css'; -interface IMenuProps extends MenuFieldProps> { +export interface IMenuAriaKitProps extends MenuFieldProps> { contextMenuPosition?: IContextMenuPosition; modal?: boolean; menuStoreProps?: MenuStoreProps; } -export const MenuAriaKit = observer>( +export const MenuAriaKit = observer( forwardRef(function MenuAriaKit({ contextMenuPosition, items, menuStoreProps, ...props }) { const store = useMenuStore(menuStoreProps); const storeState = useStoreState(store); diff --git a/webapp/packages/core-blocks/src/PropertiesTable/PropertyItem.tsx b/webapp/packages/core-blocks/src/PropertiesTable/PropertyItem.tsx index 9147b6d121..5159a2f00f 100644 --- a/webapp/packages/core-blocks/src/PropertiesTable/PropertyItem.tsx +++ b/webapp/packages/core-blocks/src/PropertiesTable/PropertyItem.tsx @@ -19,6 +19,7 @@ import { useS } from '../useS.js'; import type { IProperty } from './IProperty.js'; import classes from './PropertyItem.module.css'; import { MenuAriaKit } from '../Menu/AriaKit/MenuAriaKit.js'; +import { Menu } from '@dbeaver/ui-kit'; interface Props { property: IProperty; @@ -105,7 +106,11 @@ export const PropertyItem = observer(function PropertyItem({ property, va buttonElement={} className={s(styles, { propertyValueSelector: true })} items={property.validValues.map(value => ({ label: value, value }))} - onChange={handleValueChange} + itemRender={item => ( + handleValueChange(item.value)}> + {item.label} + + )} onSwitch={setMenuOpen} />