Skip to content

Commit 2be0a93

Browse files
committed
reduce grid-layout dependencies
1 parent bcb359b commit 2be0a93

20 files changed

+254
-106
lines changed

vuu-ui/packages/grid-layout/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
},
1313
"types": "src/index.ts",
1414
"dependencies": {
15+
"@finos/vuu-utils": "0.0.26",
1516
"@salt-ds/core": "1.37.1",
1617
"@salt-ds/lab": "1.0.0-alpha.62",
1718
"@salt-ds/styles": "0.2.1",

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@ import { CSSProperties, HTMLAttributes, ReactElement } from "react";
77
import { DragDropProviderNext } from "./drag-drop-next/DragDropProviderNext";
88
import type { ResizeOrientation } from "./grid-dom-utils";
99
import { getGridArea } from "./grid-layout-utils";
10-
import gridLayoutCss from "./GridLayout.css";
1110
import { GridLayoutContext } from "./GridLayoutContext";
1211
import { GridLayoutItemProps } from "./GridLayoutItem";
1312
import { GridLayoutStackedItem } from "./GridLayoutStackedtem";
1413
import {
1514
AriaOrientation,
15+
GridColumnsAndRows,
1616
GridLayoutChangeHandler,
17-
GridLayoutDescriptor,
1817
} from "./GridModel";
1918
import { GridPlaceholder } from "./GridPlaceholder";
2019
import { useGridLayout } from "./useGridLayout";
2120
import { useGridSplitterResizing } from "./useGridSplitterResizing";
2221

22+
import gridLayoutCss from "./GridLayout.css";
23+
2324
const classBase = "vuuGridLayout";
2425

2526
export type GridResizeable = "h" | "v" | "hv";
@@ -57,7 +58,7 @@ export interface GridLayoutProps
5758
| ReactElement<GridLayoutItemProps>
5859
| ReactElement<GridLayoutItemProps>[];
5960
"full-page"?: boolean;
60-
layout?: GridLayoutDescriptor;
61+
colsAndRows?: GridColumnsAndRows;
6162
onChange?: GridLayoutChangeHandler;
6263
}
6364

@@ -66,7 +67,7 @@ export const GridLayout = ({
6667
children: childrenProp,
6768
className,
6869
"full-page": fullPage,
69-
layout,
70+
colsAndRows,
7071
onClick,
7172
onChange,
7273
style: styleProp,
@@ -96,7 +97,7 @@ export const GridLayout = ({
9697
} = useGridLayout({
9798
children: childrenProp,
9899
id,
99-
layout,
100+
colsAndRows,
100101
onChange,
101102
});
102103

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { IconButton } from "@finos/vuu-ui-controls";
21
import { useComponentCssInjection } from "@salt-ds/styles";
32
import { useWindow } from "@salt-ds/window";
43
import cx from "clsx";
@@ -14,8 +13,8 @@ import {
1413
import { useAsDropTarget } from "./useAsDropTarget";
1514
import { useNotDropTarget } from "./useNotDropTarget";
1615

17-
import { LayoutJSON, queryClosest } from "@finos/vuu-utils";
18-
import { componentToJson } from "./componentToJson";
16+
import { queryClosest } from "@finos/vuu-utils";
17+
import { componentToJson, LayoutJSON } from "./componentToJson";
1918
import gridLayoutCss from "./GridLayout.css";
2019
import {
2120
DragSourceProvider,
@@ -26,6 +25,7 @@ import { GridModelChildItemProps } from "./GridModel";
2625
import gridSplitterCss from "./GridSplitter.css";
2726
import { useDraggable } from "./useDraggable";
2827
import { useGridChildProps } from "./useGridChildProps";
28+
import { IconButton } from "./IconButton";
2929

3030
const classBaseItem = "vuuGridLayoutItem";
3131

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
OptionalProperty,
55
} from "@finos/vuu-utils";
66
import {
7-
getBisectingGridLine,
87
gridResizeDirectionFromDropPosition,
98
doesResizeRequireNewTrack as isResizeTrackShared,
109
itemsFillColumn,
@@ -646,17 +645,23 @@ export class GridLayoutModel extends EventEmitter<GridLayoutModelEvents> {
646645
this.gridModel.tracks.splitTrack(trackType, newTrackIndex);
647646
} else {
648647
// Is there already a track line in the required position
649-
const bisectingGridLine = getBisectingGridLine(
650-
tracks,
648+
const bisectingGridTrack = this.gridModel.tracks.getBisectingTrack(
649+
trackType,
651650
resizeTrack.start,
652651
resizeTrack.end,
653652
);
654-
if (bisectingGridLine !== -1) {
653+
// console.log({ bisectingGridTrack });
654+
// const bisectingGridLine = getBisectingGridLine(
655+
// tracks,
656+
// resizeTrack.start,
657+
// resizeTrack.end,
658+
// );
659+
if (bisectingGridTrack !== -1) {
655660
const [droppedItemPosition, targetItemPosition] =
656661
splitGridChildPosition(
657662
{ column: targetGridItem.column, row: targetGridItem.row },
658663
splitDirection,
659-
bisectingGridLine,
664+
bisectingGridTrack,
660665
);
661666

662667
updates.push([droppedItemId, droppedItemPosition]);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
import { GridLayoutItemProps } from "./GridLayoutItem";
1616
import { layoutToJSON } from "./layoutToJson";
1717
import { layoutFromJson } from "./layoutFromJson";
18-
import { LayoutJSON } from "@finos/vuu-utils";
18+
import { LayoutJSON } from "./componentToJson";
1919

2020
export type GridChildElementsChangeHandler = (
2121
id: string,

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

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export type TrackSize = number | CSSTrackSize;
2525
export const isFractionUnit = (trackSize: TrackSize) =>
2626
typeof trackSize === "string" && trackSize.endsWith("fr");
2727

28-
export const isPixelUnit = (trackSize: TrackSize) =>
28+
export const isPixelUnit = (trackSize: TrackSize): trackSize is CSSTrackSize =>
2929
typeof trackSize === "string" && trackSize.endsWith("px");
3030

3131
const NO_SPLITTERS: ISplitter[] = [];
@@ -59,13 +59,16 @@ export const isMapBasedLayout = (
5959
Record<string, GridLayoutChildItemDescriptor>
6060
> => !Array.isArray(layout.gridLayoutItems);
6161

62-
export type GridLayoutDescriptor<
63-
T extends GridLayoutChildItemDescriptors = GridLayoutChildItemDescriptors,
64-
> = {
62+
export interface GridColumnsAndRows {
6563
cols: TrackSize[];
6664
rows: TrackSize[];
65+
}
66+
67+
export interface GridLayoutDescriptor<
68+
T extends GridLayoutChildItemDescriptors = GridLayoutChildItemDescriptors,
69+
> extends GridColumnsAndRows {
6770
gridLayoutItems: T;
68-
};
71+
}
6972

7073
export interface GridLayoutModelCoordinates {
7174
column: GridLayoutModelPosition;
@@ -484,6 +487,18 @@ export class GridTrack {
484487
return isFractionUnit(this.#trackSize);
485488
}
486489

490+
get isPixelValue() {
491+
return isPixelUnit(this.#trackSize);
492+
}
493+
494+
get isNumber() {
495+
return typeof this.#trackSize === "number";
496+
}
497+
498+
get isMeasured() {
499+
return this.measuredValue !== -1;
500+
}
501+
487502
get measuredValue() {
488503
return this.#measuredValue ?? -1;
489504
}
@@ -502,9 +517,13 @@ export class GridTrack {
502517
}
503518
}
504519

505-
get numericValue() {
506-
if (typeof this.#trackSize === "number") {
507-
return this.#trackSize;
520+
get hasNumericValue() {
521+
return this.isNumber || this.isPixelValue || this.isMeasured;
522+
}
523+
524+
get numericValue(): number {
525+
if (this.isNumber) {
526+
return this.#trackSize as number;
508527
} else if (isPixelUnit(this.#trackSize)) {
509528
return parseInt(this.#trackSize);
510529
} else if (this.#measuredValue !== -1) {
@@ -611,6 +630,42 @@ export class GridTracks extends EventEmitter<GridTrackEvents> {
611630
}
612631
}
613632

633+
getBisectingTrack(
634+
trackType: TrackType,
635+
startIndex: number,
636+
endIndex: number,
637+
) {
638+
console.log(
639+
`[GridTracks] getBisectingTrack (${trackType}) [${startIndex} : ${endIndex}] `,
640+
);
641+
642+
const tracks = this.getTracks(trackType);
643+
const tracksInRange = tracks.slice(startIndex - 1, endIndex);
644+
if (!tracksInRange.every((track) => track.hasNumericValue)) {
645+
this.measure(trackType);
646+
}
647+
648+
if (endIndex - startIndex > 1) {
649+
// Total the sizes between start and end
650+
// find the half way point
651+
// see if an existing edge occurs at that point (or wiuthin .5 pixesl, if decimal)
652+
}
653+
let size = 0;
654+
for (let i = startIndex - 1; i < endIndex - 1; i++) {
655+
size += tracks[i].numericValue;
656+
}
657+
const halfSize = size / 2;
658+
659+
size = 0;
660+
for (let i = startIndex - 1; i < endIndex - 1; i++) {
661+
size += tracks[i].numericValue;
662+
if (Math.abs(halfSize - size) < 1) {
663+
return i + 2;
664+
}
665+
}
666+
return -1;
667+
}
668+
614669
splitTrack(trackType: TrackType, trackIndex: number) {
615670
console.log(`[GridTracks] splitTrack (${trackType}) [${trackIndex}] `);
616671

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.vuuIcon {
2+
--vuu-icon-left: 0;
3+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { HTMLAttributes } from "react";
2+
import cx from "clsx";
3+
import { useComponentCssInjection } from "@salt-ds/styles";
4+
import { useWindow } from "@salt-ds/window";
5+
6+
import iconCss from "./Icon.css";
7+
8+
const classBase = "vuuIcon";
9+
10+
export interface IconProps extends HTMLAttributes<HTMLSpanElement> {
11+
name: string;
12+
size?: number;
13+
}
14+
15+
export const Icon = ({
16+
className,
17+
name,
18+
size,
19+
style: styleProp,
20+
...htmlAttributes
21+
}: IconProps) => {
22+
const targetWindow = useWindow();
23+
useComponentCssInjection({
24+
testId: "vuu-icon",
25+
css: iconCss,
26+
window: targetWindow,
27+
});
28+
29+
const style =
30+
typeof size === "number"
31+
? { ...styleProp, "--vuu-icon-size": `${size}px` }
32+
: styleProp;
33+
return (
34+
<span
35+
{...htmlAttributes}
36+
className={cx(classBase, className)}
37+
data-icon={name}
38+
role="img"
39+
style={style}
40+
/>
41+
);
42+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.vuuIconButton {
2+
--saltButton-padding: 0;
3+
--saltButton-minWidth: var(--salt-size-base);
4+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import cx from "clsx";
2+
import { Button, ButtonProps } from "@salt-ds/core";
3+
import { useComponentCssInjection } from "@salt-ds/styles";
4+
import { useWindow } from "@salt-ds/window";
5+
import { Icon } from "./Icon";
6+
import { forwardRef } from "react";
7+
8+
import iconButtonCss from "./IconButton.css";
9+
10+
const classBase = "vuuIconButton";
11+
12+
export interface IconButtonProps extends Omit<ButtonProps, "children"> {
13+
icon: string;
14+
size?: number;
15+
}
16+
17+
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
18+
function IconButton(
19+
{ "aria-label": ariaLabel, className, icon, size, ...buttonProps },
20+
ref
21+
) {
22+
const targetWindow = useWindow();
23+
useComponentCssInjection({
24+
testId: "vuu-icon-button",
25+
css: iconButtonCss,
26+
window: targetWindow,
27+
});
28+
29+
return (
30+
<Button {...buttonProps} className={cx(classBase, className)} ref={ref}>
31+
<Icon aria-label={ariaLabel} name={icon} size={size} />
32+
</Button>
33+
);
34+
}
35+
);

0 commit comments

Comments
 (0)