@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
104 lines (103 loc) • 9.57 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { defaultDragProxyMove, DragList } from '../dnd';
import { Icon } from '../icons';
import SimpleButton from '../SimpleButton';
import { DragAndDropContext } from './DragAndDropContext';
import { scopeDragId, scopeListId, tabIndexFromScopedListId, unscopeDragId } from './dragScope';
import { Box, Flex } from '../Flex';
import { cn } from '../../lib/utils';
export function TabList({ tabs, onTabsChange, onRemoveTab, onRemoveToolbar, onChangeTabName, disabled, onNewTab, variant = 'columns', }) {
const isRows = variant === 'rows';
const { dragScope } = React.useContext(DragAndDropContext);
const tabsListId = scopeListId(dragScope, 'TABS');
const tabIdsRef = React.useRef(new WeakMap());
const nextTabIdRef = React.useRef(0);
const getTabStableId = React.useCallback((tab) => {
const existingId = tabIdsRef.current.get(tab);
if (existingId) {
return existingId;
}
const newId = `dashboard-tab-${String(nextTabIdRef.current++)}`;
tabIdsRef.current.set(tab, newId);
return newId;
}, []);
return (_jsx(DragList, { dragListId: tabsListId, orientation: isRows ? 'vertical' : 'horizontal', dragStrategy: "proxy", preserveDragSpace: true, onDragProxyMove: defaultDragProxyMove, onDrop: (sortedIndexes) => {
const newTabs = sortedIndexes.map((i) => tabs[i]);
onTabsChange(newTabs);
}, children: (listDomProps) => (_jsxs("div", { ...listDomProps, className: cn('ab-ModuleSelector__TabList twa:flex', isRows
? 'ab-ModuleSelector__TabList--rows twa:flex-col twa:gap-2'
: 'twa:flex-1 twa:overflow-auto', listDomProps.className), "data-name": "dashboard-tabs", children: [tabs.map((tab, tabIndex) => {
const tabId = getTabStableId(tab);
return (_jsx(TabItem, { disabled: disabled, variant: variant, tabId: tabId, tabIndex: tabIndex, tabs: tabs, onTabsChange: onTabsChange, tab: tab, onRemove: () => onRemoveTab(tabIndex), onRemoveToolbar: (toolbarIndex) => onRemoveToolbar(tabIndex, toolbarIndex), onChangeTabName: (tabName) => onChangeTabName(tabIndex, tabName) }, tabIndex));
}), !disabled && onNewTab ? (isRows ? (_jsxs(Flex, { alignItems: "center", className: "twa:gap-2 twa:rounded-standard twa:border twa:border-dashed twa:cursor-pointer twa:px-3 twa:py-2 twa:text-sm twa:italic twa:hover:bg-primarylight", onClick: onNewTab, children: [_jsx(Icon, { name: "plus", size: 16 }), "Add tab"] })) : (_jsx(Flex, { alignItems: "center", justifyContent: "center", className: "ab-ModuleSelector__TabItem twa:min-w-32 twa:border-dashed twa:cursor-pointer twa:bg-primarylight twa:text-primary-foreground twa:hover:bg-primary", onClick: onNewTab, children: _jsxs("div", { className: "twa:text-8 twa:flex twa:flex-col twa:gap-4 twa:items-center twa:italic", children: [_jsx(Icon, { name: "plus", size: 32 }), "Click to add tab"] }) }))) : null] })) }));
}
export function TabItem({ tab, tabId, tabIndex, tabs, onTabsChange, onRemove, onRemoveToolbar, onChangeTabName, disabled, variant = 'columns', }) {
const context = React.useContext(DragAndDropContext);
const isDragDisabled = disabled || !context.permittedActions.dragAndDropTab;
const isRows = variant === 'rows';
const tabsListId = scopeListId(context.dragScope, 'TABS');
return (_jsx(DragList.DraggableItem, { dragListId: tabsListId, id: scopeDragId(context.dragScope, tabId), children: (itemDomProps) => {
const { onPointerDown, ...restDomProps } = itemDomProps;
let showHeader = true;
if (tab.Name === '' &&
!context.permittedActions.editTabName &&
!context.permittedActions.deleteTab) {
showHeader = false;
}
return (_jsxs("div", { ...restDomProps, className: cn('twa:bg-background', 'twa:select-none', 'ab-ModuleSelector__TabItem', isRows ? 'ab-ModuleSelector__TabItem--row' : 'twa:min-w-32', restDomProps.className), "data-name": "dashboard-tab", children: [showHeader ? (_jsxs("div", { className: cn('ab-ModuleSelector__TabItem__header', isRows && 'ab-ModuleSelector__TabItem__header--row'), children: [_jsx("div", { ...(!isDragDisabled ? { onPointerDown } : {}), style: context.permittedActions.dragAndDropTab ? {} : { display: 'none' }, children: _jsx(Icon, { name: "drag" }) }), context.permittedActions.editTabName ? (_jsx("input", { className: "ab-ModuleSelector__TabItem__header-input", type: "text", disabled: disabled, value: tab.Name, placeholder: isRows ? 'Tab name' : undefined, onChange: (event) => {
onChangeTabName(event.target.value);
} })) : (tab.Name), context.permittedActions.deleteTab && (_jsx(SimpleButton, { disabled: disabled, icon: "delete", variant: "text", onClick: onRemove }))] })) : null, _jsx(ToolbarList, { disabled: disabled, toolbars: tab.Items, tabIndex: tabIndex, tabs: tabs, onTabsChange: onTabsChange, onRemove: onRemoveToolbar, compact: isRows, embedded: isRows, orientation: isRows ? 'horizontal' : 'vertical' })] }));
} }));
}
export function ToolbarList({ toolbars, tabIndex, tabs, onTabsChange, onRemove, disabled, orientation = 'vertical', compact = false, embedded = false, }) {
const { dragScope, unusedListIds } = React.useContext(DragAndDropContext);
const listId = String(tabIndex);
const scopedListId = scopeListId(dragScope, listId);
const acceptDropsFrom = React.useMemo(() => {
const sources = unusedListIds.map((unusedListId) => scopeListId(dragScope, unusedListId));
tabs.forEach((_, i) => {
if (i !== tabIndex)
sources.push(scopeListId(dragScope, String(i)));
});
return sources;
}, [dragScope, unusedListIds, tabIndex, tabs]);
return (_jsx(DragList, { dragListId: scopedListId, orientation: orientation, acceptDropsFrom: [...acceptDropsFrom, scopedListId], onDragProxyMove: defaultDragProxyMove, onDrop: (sortedIndexes) => {
const newItems = sortedIndexes.map((i) => toolbars[i]);
onTabsChange(tabs.map((t, i) => (i === tabIndex ? { ...t, Items: newItems } : t)));
}, shouldAcceptDrop: ({ dragItem, dragSourceListId }) => {
const toolbarId = unscopeDragId(dragItem.id);
const sourceTabIndex = tabIndexFromScopedListId(dragSourceListId);
if (sourceTabIndex === tabIndex) {
return true;
}
return !toolbars.includes(toolbarId);
}, onAcceptDrop: ({ dragItemId, dropIndex }) => {
const toolbarId = unscopeDragId(dragItemId);
onTabsChange(tabs.map((tab, i) => {
if (i !== tabIndex || tab.Items.includes(toolbarId)) {
return tab;
}
const items = [...tab.Items];
items.splice(Math.min(dropIndex, items.length), 0, toolbarId);
return { ...tab, Items: items };
}));
}, children: (listDomProps, context) => (_jsxs(Box, { ...listDomProps, className: cn('ab-ModuleSelector__ToolbarList', listDomProps.className, {
'ab-ModuleSelector__ToolbarList--compact': compact,
'ab-ModuleSelector__ToolbarList--embedded': embedded,
'ab-ModuleSelector__ToolbarList--horizontal': orientation === 'horizontal',
'twa:bg-(--ab-dashboard-tab-drop-target__background) ab-ModuleSelector__ToolbarList--accent-drop': context.dropTargetListId === scopedListId && context.status === 'accepted',
'twa:bg-error/30 ab-ModuleSelector__ToolbarList--reject-drop': context.dropTargetListId === scopedListId && context.status === 'rejected',
}), "data-name": "dashboard-toolbar-drop-target", children: [toolbars?.map((toolbar, toolbarIndex) => (_jsx(ToolbarItem, { disabled: disabled, compact: compact, toolbar: toolbar, onRemove: () => onRemove(toolbarIndex) }, toolbar))), toolbars.length === 0 ? (_jsx("div", { className: cn('ab-ModuleSelector__ToolbarList__placeholder twa:italic twa:text-center', compact
? 'twa:flex twa:items-center twa:min-h-[2.5rem] twa:px-2 twa:text-sm'
: 'twa:flex twa:items-center twa:justify-center twa:h-full'), children: "Drag and drop toolbar here" })) : null] })) }));
}
export function ToolbarItem({ toolbar, onRemove, disabled, compact = false, }) {
const { availableItems, dragScope } = React.useContext(DragAndDropContext);
const currentItem = availableItems.find((t) => t.Id === toolbar);
const title = currentItem ? currentItem.Title : toolbar;
return (_jsx(DragList.DraggableItem, { id: scopeDragId(dragScope, toolbar), children: (itemDomProps) => {
const { onPointerDown, ...restDomProps } = itemDomProps;
return (_jsxs(Flex, { ...restDomProps, ...(disabled ? {} : { onPointerDown }), className: cn('ab-ModuleSelector__ToolbarItem ab-ModuleSelector__DraggableChip twa:text-3 twa:rounded-standard twa:gap-1', compact ? 'twa:px-2 twa:py-1 twa:shrink-0' : 'twa:mb-1 twa:pl-1 twa:pr-0', restDomProps.className), alignItems: "center", children: [_jsx(Icon, { name: "drag", className: "twa:shrink-0 twa:opacity-60", size: 14 }), _jsx("div", { className: "twa:flex-1 twa:min-w-0", children: title }), _jsx(SimpleButton, { disabled: disabled, icon: "close", variant: "text", className: "twa:p-1", onClick: onRemove })] }));
} }));
}