Skip to content

Commit

Permalink
tabbed layout support
Browse files Browse the repository at this point in the history
  • Loading branch information
heswell committed Sep 6, 2024
1 parent 717a6bd commit d33d891
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 168 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import {
GridLayoutItemProps,
Stack,
renderTabsForStack,
useDraggable,
useGridLayoutDragStartHandler,
useGridLayoutProps,
useGridLayoutProviderDispatch
useGridLayoutProps
} from "@finos/vuu-layout";
import { IconButton } from "@finos/vuu-ui-controls";
import { useComponentCssInjection } from "@salt-ds/styles";
import { useWindow } from "@salt-ds/window";
import cx from "clsx";
import { DragEvent, MouseEventHandler, useCallback } from "react";
import { DragEvent, useCallback, useState } from "react";
import { useAsDropTarget } from "./useAsDropTarget";
import { useNotDropTarget } from "./useNotDropTarget";

import { queryClosest } from "@finos/vuu-utils";
import gridLayoutCss from "./GridLayout.css";
import gridSplitterCss from "./GridSplitter.css";
import { Tabstrip } from "@finos/vuu-ui-controls";

const classBaseItem = "vuuGridLayoutItem";

export const GridLayoutStackedItem = ({
active: activeProp = 0,
children,
className: classNameProp,
header,
Expand All @@ -29,7 +31,9 @@ export const GridLayoutStackedItem = ({
style: styleProp,
title,
...htmlAttributes
}: GridLayoutItemProps) => {
}: GridLayoutItemProps & {
active?: number;
}) => {
const targetWindow = useWindow();
useComponentCssInjection({
testId: "vuu-grid-layout",
Expand All @@ -42,17 +46,9 @@ export const GridLayoutStackedItem = ({
window: targetWindow
});

const dispatch = useGridLayoutProviderDispatch();
const layoutProps = useGridLayoutProps(id);
const onDragStart = useGridLayoutDragStartHandler();

const onClose = useCallback<MouseEventHandler<HTMLButtonElement>>(
(evt) => {
evt.stopPropagation();
dispatch({ type: "close", id });
},
[dispatch, id]
);
const [active, setActive] = useState(activeProp);

const getPayload = useCallback(
(evt: DragEvent<Element>): [string, string] => {
Expand All @@ -73,6 +69,8 @@ export const GridLayoutStackedItem = ({
onDragStart
});

// const TabstripProps = useMemo<TabstripProps>(() => ({}), []);

const className = cx(classBaseItem, {
[`${classBaseItem}-resizeable-h`]: resizeable === "h",
[`${classBaseItem}-resizeable-v`]: resizeable === "v",
Expand All @@ -81,10 +79,11 @@ export const GridLayoutStackedItem = ({

const style = {
...styleProp,
...layoutProps,
"--header-height": header ? "25px" : "0px"
...layoutProps
};

const stackId = `stack-${id}`;

return (
<div
{...htmlAttributes}
Expand All @@ -95,25 +94,18 @@ export const GridLayoutStackedItem = ({
key={id}
style={style}
>
{header ? (
<div
className={cx(`${classBaseItem}Header`, dropTargetClassName)}
data-drop-target="tabs"
>
<span className={`${classBaseItem}Header-title`} draggable>
{title}
</span>
<IconButton
className={`${classBaseItem}Header-close`}
data-align="right"
icon="close"
onClick={onClose}
variant="secondary"
/>
</div>
) : null}
<div
className={cx(`${classBaseItem}Header`, dropTargetClassName)}
data-drop-target="tabs"
>
<Tabstrip activeTabIndex={active} onActiveChange={setActive}>
{renderTabsForStack(stackId, children)}
</Tabstrip>
</div>
<div className={cx(`${classBaseItem}Content`, dropTargetClassName)}>
{children}
<Stack active={active} id={stackId} showTabs={false}>
{children}
</Stack>
</div>
</div>
);
Expand Down
39 changes: 39 additions & 0 deletions vuu-ui/packages/vuu-layout/src/grid-layout/react-element-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { ReactElement } from "react";

export const getChildComponent = (
children: ReactElement[],
gridItemId: string
): ReactElement => {
const targetGridItem = children.find(
(child) => child.props.id === gridItemId
);
if (targetGridItem) {
const childComponent = targetGridItem.props.children;
if (React.isValidElement(childComponent)) {
return childComponent;
} else if (Array.isArray(childComponent)) {
return childComponent.at(0) as ReactElement;
} else {
throw Error(`invalid child component`);
}
} else {
throw Error(`getChildComponent #${gridItemId} not found`);
}
};

export const addChildComponentToStack = (
stackElement: ReactElement,
childElement: ReactElement
) => {
if (Array.isArray(stackElement.props.children)) {
console.log(`children is an array`);
}

const stackChildren = stackElement.props.children;
// can we add an imperative API method to Stack ?
return React.cloneElement(
stackElement,
{},
stackChildren.concat(childElement)
);
};
Loading

0 comments on commit d33d891

Please sign in to comment.