mirror of https://github.com/buster-so/buster.git
dropdown update
This commit is contained in:
parent
9fea44cc60
commit
dfede461bc
|
@ -21,22 +21,28 @@ export const SaveToCollectionsDropdown: React.FC<{
|
||||||
const [openCollectionModal, setOpenCollectionModal] = React.useState(false);
|
const [openCollectionModal, setOpenCollectionModal] = React.useState(false);
|
||||||
const [showDropdown, setShowDropdown] = React.useState(false);
|
const [showDropdown, setShowDropdown] = React.useState(false);
|
||||||
|
|
||||||
const items: DropdownProps['items'] = useMemo(
|
const items: DropdownProps['items'] = useMemo(() => {
|
||||||
() =>
|
const collectionsItems = (collectionsList || []).map<DropdownItem>((collection) => {
|
||||||
(collectionsList || []).map<DropdownItem>((collection) => {
|
return {
|
||||||
return {
|
value: collection.id,
|
||||||
value: collection.id,
|
label: collection.name,
|
||||||
label: collection.name,
|
selected: selectedCollections.some((id) => id === collection.id),
|
||||||
selected: selectedCollections.some((id) => id === collection.id),
|
onClick: () => onClickItem(collection),
|
||||||
onClick: () => onClickItem(collection),
|
link: createBusterRoute({
|
||||||
link: createBusterRoute({
|
route: BusterRoutes.APP_COLLECTIONS_ID,
|
||||||
route: BusterRoutes.APP_COLLECTIONS_ID,
|
collectionId: collection.id
|
||||||
collectionId: collection.id
|
})
|
||||||
})
|
};
|
||||||
};
|
});
|
||||||
}),
|
|
||||||
[collectionsList, selectedCollections]
|
return [
|
||||||
);
|
...collectionsItems,
|
||||||
|
{
|
||||||
|
value: 'new',
|
||||||
|
label: 'New collection'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}, [collectionsList, selectedCollections]);
|
||||||
|
|
||||||
const onClickItem = useMemoizedFn((collection: BusterCollectionListItem) => {
|
const onClickItem = useMemoizedFn((collection: BusterCollectionListItem) => {
|
||||||
const isSelected = selectedCollections.some((id) => id === collection.id);
|
const isSelected = selectedCollections.some((id) => id === collection.id);
|
||||||
|
@ -63,6 +69,7 @@ export const SaveToCollectionsDropdown: React.FC<{
|
||||||
|
|
||||||
const onOpenChange = useMemoizedFn((open: boolean) => {
|
const onOpenChange = useMemoizedFn((open: boolean) => {
|
||||||
setShowDropdown(open);
|
setShowDropdown(open);
|
||||||
|
console.log('open', open);
|
||||||
});
|
});
|
||||||
|
|
||||||
const onClick = useMemoizedFn(() => {
|
const onClick = useMemoizedFn(() => {
|
||||||
|
@ -84,11 +91,12 @@ export const SaveToCollectionsDropdown: React.FC<{
|
||||||
side="bottom"
|
side="bottom"
|
||||||
align="start"
|
align="start"
|
||||||
menuHeader={'Save to a collection'}
|
menuHeader={'Save to a collection'}
|
||||||
open={showDropdown}
|
|
||||||
onOpenChange={onOpenChange}
|
onOpenChange={onOpenChange}
|
||||||
footerContent={memoizedButton}
|
footerContent={memoizedButton}
|
||||||
items={items}>
|
items={items}>
|
||||||
<AppTooltip title={showDropdown ? '' : 'Save to collection'}>{children} </AppTooltip>
|
<div>
|
||||||
|
<AppTooltip title={showDropdown ? '' : 'Save to collection'}>{children} </AppTooltip>
|
||||||
|
</div>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
||||||
<NewCollectionModal
|
<NewCollectionModal
|
||||||
|
|
|
@ -540,6 +540,13 @@ export const WithFooterContent: Story = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithFooterAndHeader: Story = {
|
||||||
|
args: {
|
||||||
|
...WithFooterContent.args,
|
||||||
|
menuHeader: 'Menu...'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Example with numbered items
|
// Example with numbered items
|
||||||
export const WithNumberedItemsNoFilter: Story = {
|
export const WithNumberedItemsNoFilter: Story = {
|
||||||
args: {
|
args: {
|
||||||
|
@ -565,6 +572,7 @@ export const WithNumberedItemsNoFilter: Story = {
|
||||||
label: 'Third Item',
|
label: 'Third Item',
|
||||||
onClick: fn(),
|
onClick: fn(),
|
||||||
icon: <Storage />,
|
icon: <Storage />,
|
||||||
|
searchLabel: 'Third Item with secondary label',
|
||||||
secondaryLabel: 'With secondary label'
|
secondaryLabel: 'With secondary label'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -164,9 +164,9 @@ export const DropdownBase = <T,>({
|
||||||
className={cn('max-w-72 min-w-44', className)}
|
className={cn('max-w-72 min-w-44', className)}
|
||||||
align={align}
|
align={align}
|
||||||
side={side}
|
side={side}
|
||||||
footerContent={footerContent}>
|
footerContent={footerContent}
|
||||||
{menuHeader && (
|
headerContent={
|
||||||
<>
|
menuHeader && (
|
||||||
<DropdownMenuHeaderSelector
|
<DropdownMenuHeaderSelector
|
||||||
menuHeader={menuHeader}
|
menuHeader={menuHeader}
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
|
@ -174,10 +174,8 @@ export const DropdownBase = <T,>({
|
||||||
onSelectItem={onSelectItem}
|
onSelectItem={onSelectItem}
|
||||||
showIndex={showIndex}
|
showIndex={showIndex}
|
||||||
/>
|
/>
|
||||||
<DropdownMenuSeparator />
|
)
|
||||||
</>
|
}>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="max-h-[375px] overflow-y-auto">
|
<div className="max-h-[375px] overflow-y-auto">
|
||||||
{hasShownItem ? (
|
{hasShownItem ? (
|
||||||
<>
|
<>
|
||||||
|
@ -324,11 +322,12 @@ const DropdownItem = <T,>({
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
{icon && !loading && <span className="text-icon-color">{icon}</span>}
|
{icon && !loading && <span className="text-icon-color">{icon}</span>}
|
||||||
{loading && <CircleSpinnerLoader size={9} />}
|
|
||||||
<div className={cn('flex flex-col gap-y-1', truncate && 'overflow-hidden')}>
|
<div className={cn('flex flex-col gap-y-1', truncate && 'overflow-hidden')}>
|
||||||
<span className={cn(truncate && 'truncate')}>{label}</span>
|
<span className={cn(truncate && 'truncate')}>{label}</span>
|
||||||
{secondaryLabel && <span className="text-gray-light text2xs">{secondaryLabel}</span>}
|
{secondaryLabel && <span className="text-gray-light text2xs">{secondaryLabel}</span>}
|
||||||
</div>
|
</div>
|
||||||
|
{loading && <CircleSpinnerLoader size={9} />}
|
||||||
{shortcut && <DropdownMenuShortcut>{shortcut}</DropdownMenuShortcut>}
|
{shortcut && <DropdownMenuShortcut>{shortcut}</DropdownMenuShortcut>}
|
||||||
{link && (
|
{link && (
|
||||||
<DropdownMenuLink
|
<DropdownMenuLink
|
||||||
|
@ -511,6 +510,7 @@ const DropdownMenuHeaderSearch = <T,>({
|
||||||
<Input
|
<Input
|
||||||
autoFocus
|
autoFocus
|
||||||
variant={'ghost'}
|
variant={'ghost'}
|
||||||
|
size={'small'}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
value={text}
|
value={text}
|
||||||
onChange={onChangePreflight}
|
onChange={onChangePreflight}
|
||||||
|
|
|
@ -68,20 +68,24 @@ const DropdownMenuContent = React.forwardRef<
|
||||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {
|
||||||
footerContent?: React.ReactNode;
|
footerContent?: React.ReactNode;
|
||||||
|
headerContent?: React.ReactNode;
|
||||||
}
|
}
|
||||||
>(({ className, children, sideOffset = 4, footerContent, ...props }, ref) => {
|
>(({ className, children, sideOffset = 4, footerContent, headerContent, ...props }, ref) => {
|
||||||
const NodeWrapper = footerContent ? 'div' : 'span';
|
|
||||||
const nodeWrapperProps = footerContent ? { className: 'p-2' } : { className: '' };
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenuPrimitive.Portal>
|
<DropdownMenuPrimitive.Portal>
|
||||||
<DropdownMenuPrimitive.Content
|
<DropdownMenuPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={cn(baseContentClass, 'shadow', footerContent && 'p-0', className)}
|
className={cn(baseContentClass, 'shadow', 'p-0', className)}
|
||||||
{...props}>
|
{...props}>
|
||||||
<NodeWrapper {...nodeWrapperProps}>{children}</NodeWrapper>
|
{headerContent && (
|
||||||
{footerContent && <div className="border-t p-2">{footerContent}</div>}
|
<div className="flex flex-col">
|
||||||
|
<div className="p-1">{headerContent}</div>
|
||||||
|
<div className="bg-border h-[0.5px] w-full" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="used-for-ref-purpose">{children}</div>
|
||||||
|
{footerContent && <div className="border-t p-1">{footerContent}</div>}
|
||||||
</DropdownMenuPrimitive.Content>
|
</DropdownMenuPrimitive.Content>
|
||||||
</DropdownMenuPrimitive.Portal>
|
</DropdownMenuPrimitive.Portal>
|
||||||
);
|
);
|
||||||
|
@ -102,6 +106,7 @@ const DropdownMenuItem = React.forwardRef<
|
||||||
className={cn(
|
className={cn(
|
||||||
'relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-base outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
'relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-base outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
||||||
'focus:bg-item-hover focus:text-foreground',
|
'focus:bg-item-hover focus:text-foreground',
|
||||||
|
'dropdown-item mx-1 [&.dropdown-item:first-child]:mt-1! [&.dropdown-item:has(+.dropdown-separator)]:mb-1 [&.dropdown-item:has(~.dropdown-separator)]:mt-1 [&.dropdown-item:last-child]:mb-1!',
|
||||||
inset && 'pl-8',
|
inset && 'pl-8',
|
||||||
truncate && 'overflow-hidden',
|
truncate && 'overflow-hidden',
|
||||||
'group',
|
'group',
|
||||||
|
@ -123,7 +128,8 @@ const itemClass = cn(
|
||||||
'focus:bg-item-hover focus:text-foreground',
|
'focus:bg-item-hover focus:text-foreground',
|
||||||
'relative flex cursor-pointer items-center rounded-sm py-1.5 text-sm outline-none select-none',
|
'relative flex cursor-pointer items-center rounded-sm py-1.5 text-sm outline-none select-none',
|
||||||
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||||
'gap-1.5'
|
'gap-1.5',
|
||||||
|
'mx-1 dropdown-item [&.dropdown-item:has(+.dropdown-separator)]:mb-1 [&.dropdown-item:has(~.dropdown-separator)]:mt-1 [&.dropdown-item:first-child]:mt-1! [&.dropdown-item:last-child]:mb-1!'
|
||||||
);
|
);
|
||||||
|
|
||||||
const DropdownMenuCheckboxItemSingle = React.forwardRef<
|
const DropdownMenuCheckboxItemSingle = React.forwardRef<
|
||||||
|
|
Loading…
Reference in New Issue