mirror of https://github.com/buster-so/buster.git
sortable sidebar collapse
This commit is contained in:
parent
96fe76cfe6
commit
f923c3a428
|
@ -209,6 +209,10 @@ GlobalModals.displayName = 'GlobalModals';
|
||||||
const favoritesDropdown = (favorites: BusterUserFavorite[]): ISidebarGroup => {
|
const favoritesDropdown = (favorites: BusterUserFavorite[]): ISidebarGroup => {
|
||||||
return {
|
return {
|
||||||
label: 'Favorites',
|
label: 'Favorites',
|
||||||
|
isSortable: true,
|
||||||
|
onItemsReorder: (itemIds) => {
|
||||||
|
console.warn('onItemsReorder', itemIds);
|
||||||
|
},
|
||||||
items: favorites.map((favorite) => {
|
items: favorites.map((favorite) => {
|
||||||
const Icon = assetTypeToIcon(favorite.asset_type);
|
const Icon = assetTypeToIcon(favorite.asset_type);
|
||||||
const route = assetTypeToRoute(favorite.asset_type, favorite.id);
|
const route = assetTypeToRoute(favorite.asset_type, favorite.id);
|
||||||
|
|
|
@ -2,21 +2,21 @@ import React from 'react';
|
||||||
import { ISidebarGroup, ISidebarList, SidebarProps } from './interfaces';
|
import { ISidebarGroup, ISidebarList, SidebarProps } from './interfaces';
|
||||||
import { SidebarCollapsible } from './SidebarCollapsible';
|
import { SidebarCollapsible } from './SidebarCollapsible';
|
||||||
import { SidebarItem } from './SidebarItem';
|
import { SidebarItem } from './SidebarItem';
|
||||||
|
import { useMemoizedFn } from '@/hooks';
|
||||||
|
|
||||||
export const Sidebar: React.FC<SidebarProps> = React.memo(
|
export const Sidebar: React.FC<SidebarProps> = React.memo(
|
||||||
({ header, content, footer, activeItem, isSortable = false }) => {
|
({ header, content, footer, activeItem }) => {
|
||||||
|
const onItemsReorder = useMemoizedFn((ids: string[], contentIndex: number) => {
|
||||||
|
console.log('onItemsReorder', ids);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col overflow-hidden px-3.5 pt-4.5">
|
<div className="flex h-full flex-col overflow-hidden px-3.5 pt-4.5">
|
||||||
<div className="flex flex-col space-y-4.5 overflow-hidden">
|
<div className="flex flex-col space-y-4.5 overflow-hidden">
|
||||||
<div className="mb-5"> {header}</div>
|
<div className="mb-5"> {header}</div>
|
||||||
<div className="flex flex-grow flex-col space-y-4.5 overflow-y-auto pb-3">
|
<div className="flex flex-grow flex-col space-y-4.5 overflow-y-auto pb-3">
|
||||||
{content.map((item, index) => (
|
{content.map((item, index) => (
|
||||||
<ContentSelector
|
<ContentSelector key={index} content={item} activeItem={activeItem} />
|
||||||
key={index}
|
|
||||||
content={item}
|
|
||||||
activeItem={activeItem}
|
|
||||||
isSortable={isSortable}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,10 +31,9 @@ Sidebar.displayName = 'Sidebar';
|
||||||
const ContentSelector: React.FC<{
|
const ContentSelector: React.FC<{
|
||||||
content: SidebarProps['content'][number];
|
content: SidebarProps['content'][number];
|
||||||
activeItem: SidebarProps['activeItem'];
|
activeItem: SidebarProps['activeItem'];
|
||||||
isSortable: SidebarProps['isSortable'];
|
}> = React.memo(({ content, activeItem }) => {
|
||||||
}> = React.memo(({ content, activeItem, isSortable }) => {
|
|
||||||
if (isSidebarGroup(content)) {
|
if (isSidebarGroup(content)) {
|
||||||
return <SidebarCollapsible {...content} activeItem={activeItem} isSortable={isSortable} />;
|
return <SidebarCollapsible {...content} activeItem={activeItem} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SidebarList items={content.items} activeItem={activeItem} />;
|
return <SidebarList items={content.items} activeItem={activeItem} />;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { SidebarCollapsible } from './SidebarCollapsible';
|
||||||
import { HouseModern, MapSettings, User } from '../icons/NucleoIconOutlined';
|
import { HouseModern, MapSettings, User } from '../icons/NucleoIconOutlined';
|
||||||
import { BusterRoutes } from '../../../routes';
|
import { BusterRoutes } from '../../../routes';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { fn } from '@storybook/test';
|
||||||
|
|
||||||
const meta: Meta<typeof SidebarCollapsible> = {
|
const meta: Meta<typeof SidebarCollapsible> = {
|
||||||
title: 'UI/Sidebar/SidebarCollapsible',
|
title: 'UI/Sidebar/SidebarCollapsible',
|
||||||
|
@ -50,7 +51,9 @@ export const Default: Story = {
|
||||||
|
|
||||||
export const Sortable: Story = {
|
export const Sortable: Story = {
|
||||||
args: {
|
args: {
|
||||||
...Default.args,
|
label: 'Sortable',
|
||||||
isSortable: true
|
isSortable: true,
|
||||||
|
items: Default.args!.items!,
|
||||||
|
onItemsReorder: fn()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,12 +100,15 @@ const SortableSidebarItem: React.FC<SortableSidebarItemProps> = React.memo(({ it
|
||||||
|
|
||||||
SortableSidebarItem.displayName = 'SortableSidebarItem';
|
SortableSidebarItem.displayName = 'SortableSidebarItem';
|
||||||
|
|
||||||
export const SidebarCollapsible: React.FC<ISidebarGroup & { activeItem?: string }> = React.memo(
|
export const SidebarCollapsible: React.FC<
|
||||||
|
ISidebarGroup & { activeItem?: string; onItemsReorder?: (ids: string[]) => void }
|
||||||
|
> = React.memo(
|
||||||
({
|
({
|
||||||
label,
|
label,
|
||||||
items,
|
items,
|
||||||
isSortable = false,
|
isSortable = false,
|
||||||
activeItem,
|
activeItem,
|
||||||
|
onItemsReorder,
|
||||||
variant = 'collapsible',
|
variant = 'collapsible',
|
||||||
icon,
|
icon,
|
||||||
defaultOpen = true
|
defaultOpen = true
|
||||||
|
@ -133,7 +136,9 @@ export const SidebarCollapsible: React.FC<ISidebarGroup & { activeItem?: string
|
||||||
setSortedItems((items) => {
|
setSortedItems((items) => {
|
||||||
const oldIndex = items.findIndex((item) => item.id === active.id);
|
const oldIndex = items.findIndex((item) => item.id === active.id);
|
||||||
const newIndex = items.findIndex((item) => item.id === over?.id);
|
const newIndex = items.findIndex((item) => item.id === over?.id);
|
||||||
return arrayMove(items, oldIndex, newIndex);
|
const moveddArray = arrayMove(items, oldIndex, newIndex);
|
||||||
|
onItemsReorder?.(moveddArray.map((item) => item.id));
|
||||||
|
return moveddArray;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,6 +18,7 @@ export interface ISidebarGroup {
|
||||||
variant?: 'collapsible' | 'icon'; //default is collapsible
|
variant?: 'collapsible' | 'icon'; //default is collapsible
|
||||||
defaultOpen?: boolean; //will default to true
|
defaultOpen?: boolean; //will default to true
|
||||||
isSortable?: boolean;
|
isSortable?: boolean;
|
||||||
|
onItemsReorder?: (ids: string[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISidebarList {
|
export interface ISidebarList {
|
||||||
|
|
Loading…
Reference in New Issue