Skip to content

Commit 0acbbc4

Browse files
committed
fix tab switching issue
1 parent c6c9d2c commit 0acbbc4

File tree

7 files changed

+76
-64
lines changed

7 files changed

+76
-64
lines changed

vuu-ui/packages/grid-layout/src/GridLayoutItem.tsx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ import { IconButton } from "./IconButton";
3030
const classBaseItem = "vuuGridLayoutItem";
3131

3232
export interface GridLayoutItemProps
33-
extends Omit<
34-
GridModelChildItemProps,
35-
"contentDetached" | "contentVisible" | "type"
36-
>,
33+
extends Omit<GridModelChildItemProps, "contentDetached" | "type">,
3734
Omit<
3835
HTMLAttributes<HTMLDivElement>,
3936
"id" | "onDragStart" | "onDrop" | "style"
@@ -75,6 +72,7 @@ const getDragSource: DragSourceProvider = (evt) => {
7572
export const GridLayoutItem = ({
7673
children,
7774
className: classNameProp,
75+
contentVisible: contentVisibleProp,
7876
"data-drop-target": dataDropTarget,
7977
header: headerProp,
8078
height,
@@ -109,6 +107,7 @@ export const GridLayoutItem = ({
109107
title,
110108
...layoutProps
111109
} = useGridChildProps({
110+
contentVisible: contentVisibleProp,
112111
dropTarget: dataDropTarget,
113112
header: headerProp,
114113
height,
@@ -120,15 +119,6 @@ export const GridLayoutItem = ({
120119
width,
121120
});
122121

123-
// console.log(
124-
// `[GridLayoutItem] #${id}
125-
// contentDetached=${contentDetached}
126-
// contentVisible=${contentVisible}
127-
// stackId=${stackId}
128-
// dropTarget = ${dropTarget}
129-
// `,
130-
// );
131-
132122
useEffect(
133123
() => () => {
134124
console.log(`unmount layout item ${id}`);
@@ -155,6 +145,8 @@ export const GridLayoutItem = ({
155145
onDragStart,
156146
});
157147

148+
console.log(`[GridLayoutItem] #${id} contentVisible ${contentVisible}`);
149+
158150
const className = cx(classBaseItem, {
159151
"vuu-detached": contentDetached,
160152
"vuu-stacked": stacked && !contentDetached,

vuu-ui/packages/grid-layout/src/GridLayoutProvider.tsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,24 +128,6 @@ export const GridLayoutProvider = (
128128
return undefined;
129129
}, []);
130130

131-
/*
132-
// return Object.entries(childElementMap).map(
133-
// ([gridLayoutItemId, element]) => {
134-
// // TODO type IS in here although the types shouldn't allow it
135-
// const { gridArea, type, ...gridLayoutItemProps } =
136-
// layout.gridLayoutItems[gridLayoutItemId];
137-
// return (
138-
// <GridLayoutItem
139-
// {...gridLayoutItemProps}
140-
// id={gridLayoutItemId}
141-
// style={{ gridArea }}
142-
// key={gridLayoutItemId}
143-
// >
144-
// {element}
145-
// </GridLayoutItem>
146-
// );
147-
148-
*/
149131
const getSavedGrid = useCallback(
150132
(id: string): DeserializedGridLayout | undefined => {
151133
const layoutJSON = gridChildItemsMap.get(id);

vuu-ui/packages/grid-layout/src/GridModel.ts

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,17 @@ export const isPixelUnit = (trackSize: TrackSize): trackSize is CSSTrackSize =>
3030

3131
const NO_SPLITTERS: ISplitter[] = [];
3232

33+
//TODO shouldn't id be here ?
3334
export interface GridLayoutChildItemDescriptor {
34-
/**
35-
* componentId is only required when a GridLayout is declared using JSX
36-
* and child components are directly nested within GridLayout without GridItem
37-
* wrappers.
38-
* Each child component must have a unique id. The componentId here is used
39-
* to match the with the associated component. If GridItem wrappers are included
40-
* explicitly in the JSX, componentId is not required in the
41-
* GridLayoutChildItemDescriptor.
42-
*/
43-
componentId?: string;
35+
contentVisible?: boolean;
4436
dropTarget?: boolean | string;
4537
gridArea: string;
4638
header?: boolean;
4739
resizeable?: GridModelItemResizeable;
40+
/**
41+
* For GridLayoutItems that are 'stacked' (e.g. displayed in tabbed container)
42+
* this is the id of the associated StackedLayoutItem.
43+
*/
4844
stackId?: string;
4945
title?: string;
5046
}
@@ -81,21 +77,13 @@ export interface GridLayoutModelCoordinates {
8177
row: GridLayoutModelPosition;
8278
}
8379

84-
export interface GridModelChildItemProps {
80+
export interface GridModelChildItemProps
81+
extends Omit<GridLayoutChildItemDescriptor, "gridArea"> {
8582
contentVisible?: boolean;
86-
dropTarget?: boolean | string;
8783
fixed?: boolean;
88-
header?: boolean;
8984
height?: number;
9085
id: string;
91-
/**
92-
* For GridLayoutItems that are 'stacked' (e.g. displayed in tabbed container)
93-
* this is the id of the associated StackedLayoutItem.
94-
*/
95-
stackId?: string;
96-
resizeable?: GridModelItemResizeable;
9786
style: GridChildItemStyle;
98-
title?: string;
9987
type?: GridModelItemType;
10088
width?: number;
10189
}
@@ -952,7 +940,11 @@ export class GridModel extends EventEmitter<GridModelEvents> {
952940
}
953941
};
954942

955-
setTabState(stackId: string, childItems: GridModelChildItem[]) {
943+
setTabState(
944+
stackId: string,
945+
childItems: GridModelChildItem[],
946+
activeItem = 0,
947+
) {
956948
console.log(`[GridModel] setTabState ${stackId}`);
957949
let tabState = this.#tabState.get(stackId);
958950
if (tabState) {
@@ -962,15 +954,15 @@ export class GridModel extends EventEmitter<GridModelEvents> {
962954
id,
963955
label: title ?? `Label-${index + 1}`,
964956
}));
965-
tabState = new TabState(stackId, 0, tabs);
957+
tabState = new TabState(stackId, activeItem, tabs);
966958

967959
tabState.on("active-change", this.handleTabSelectionChange);
968960
tabState.on("tab-added", this.handleTabAdded);
969961
tabState.on("tab-detached", this.handleTabDetached);
970962
tabState.on("tabs-change", this.handleTabsChange);
971963
tabState.on("tabs-removed", this.handleTabsRemoved);
972964

973-
this.activateStackedChildItem(stackId, tabs[0]);
965+
this.activateStackedChildItem(stackId, tabs[activeItem]);
974966

975967
this.#tabState.set(stackId, tabState);
976968
return tabState;
@@ -1034,16 +1026,37 @@ export class GridModel extends EventEmitter<GridModelEvents> {
10341026
gridLayoutItems: this.#childItems.reduce<GridLayoutChildItemDescriptors>(
10351027
(
10361028
result,
1037-
{ id, column, dropTarget, header, resizeable, row, stackId, title },
1038-
) => {
1039-
result[id.replace(/^grid-/, "")] = {
1029+
{
1030+
id,
1031+
column,
1032+
contentVisible,
10401033
dropTarget,
1041-
gridArea: `${row.start}/${column.start}/${row.end}/${column.end}`,
10421034
header,
10431035
resizeable,
1036+
row,
10441037
stackId,
10451038
title,
1046-
};
1039+
type,
1040+
},
1041+
) => {
1042+
console.log(`[GridModel] toGridLayoutDescriptor ${id} = ${type}`);
1043+
if (stackId) {
1044+
console.log(
1045+
`[GridModel] is a stacked item, active item ? ${contentVisible === true} `,
1046+
);
1047+
}
1048+
// The stacked-content gridItems are a runtime construct, no need to serialize
1049+
if (type !== "stacked-content") {
1050+
result[id] = {
1051+
contentVisible,
1052+
dropTarget,
1053+
gridArea: `${row.start}/${column.start}/${row.end}/${column.end}`,
1054+
header,
1055+
resizeable,
1056+
stackId,
1057+
title,
1058+
};
1059+
}
10471060
return result;
10481061
},
10491062
{},
@@ -1148,12 +1161,20 @@ export class GridModel extends EventEmitter<GridModelEvents> {
11481161
private addChildItems(childItems: GridLayoutChildItemDescriptors) {
11491162
for (const [
11501163
id,
1151-
{ dropTarget, header, resizeable, stackId, title, ...item },
1164+
{
1165+
contentVisible,
1166+
dropTarget,
1167+
header,
1168+
resizeable,
1169+
stackId,
1170+
title,
1171+
...item
1172+
},
11521173
] of Object.entries(childItems)) {
11531174
const { column, row } = getGridPosition(item.gridArea);
11541175
this.addChildItem(
11551176
new GridModelChildItem({
1156-
// id: `grid-${id}`,
1177+
contentVisible,
11571178
id,
11581179
column,
11591180
dropTarget,

vuu-ui/packages/grid-layout/src/grid-layout-utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,17 @@ export const isFixedWidthChildItem = (item: GridModelChildItem) =>
410410
export const getGridArea = ({ column, row }: GridLayoutModelCoordinates) =>
411411
`${row.start}/${column.start}/${row.end}/${column.end}`;
412412

413+
export const getActiveIndex = (childItems: GridModelChildItem[]) => {
414+
const index = childItems.findIndex((item) => item.contentVisible);
415+
if (childItems.length === 0) {
416+
return -1;
417+
} else if (index === -1) {
418+
return 0;
419+
} else {
420+
return index;
421+
}
422+
};
423+
413424
export const getSharedGridPosition = (
414425
childItems: GridModelChildItem[],
415426
): GridLayoutModelCoordinates => {

vuu-ui/packages/grid-layout/src/useGridChildProps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const useGridChildProps = ({
2323

2424
let childItem = gridModel?.getChildItem(id);
2525
if (childItem) {
26-
// console.log(`already registered child item ${id}`);
26+
console.log(`already registered child item ${id}`);
2727
} else {
2828
const { column, row } = getGridPosition(style.gridArea);
2929
childItem = new GridModelChildItem({

vuu-ui/packages/grid-layout/src/useGridLayout.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ import {
2727
setGridColumn,
2828
setGridRow,
2929
} from "./grid-dom-utils";
30-
import { getGridArea, getSharedGridPosition } from "./grid-layout-utils";
30+
import {
31+
getActiveIndex,
32+
getGridArea,
33+
getSharedGridPosition,
34+
} from "./grid-layout-utils";
3135
import {
3236
GridLayoutDispatch,
3337
GridLayoutDropHandler,
@@ -697,7 +701,8 @@ export const useGridLayout = ({
697701
const tabs = gridModel.getChildItem(stackId);
698702
if (tabs === undefined) {
699703
const { column, row } = getSharedGridPosition(items);
700-
gridModel.setTabState(stackId, items);
704+
const activeIndex = getActiveIndex(items);
705+
gridModel.setTabState(stackId, items, activeIndex);
701706
const stackedItem = new GridModelChildItem({
702707
column,
703708
id: stackId,

vuu-ui/showcase/src/examples/html/GridLayoutPersistence.examples.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export const SingleStackDeserialized = () => {
9191
title: "Blue",
9292
},
9393
red: {
94+
contentVisible: true,
9495
gridArea: "1/1/2/2",
9596
header: true,
9697
resizeable: "hv",

0 commit comments

Comments
 (0)