Skip to content

Commit

Permalink
Merge branch 'feat/dimensions-constraints-core'
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianCraig committed Mar 20, 2020
2 parents 1265bef + ee83220 commit 69cef53
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/LayoutContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
LayoutDefinition,
ConstraintDefinition
} from "./constraints/definition";
import { appLayout } from "./examples/appLayout";


export interface LayoutContextInterface {
Expand Down Expand Up @@ -56,7 +57,7 @@ const defaultConstraints: ConstraintDefinition[] = [
];

export const LayoutProvider: FunctionComponent = ({ children }) => {
const [layout, setLayout] = useState<LayoutDefinition>({});
const [layout, setLayout] = useState<LayoutDefinition>(appLayout);
const [addingComponent, setAddingComponent] = useState<boolean>(false)
const [selectedComponent, setSelectedComponent] = useState<string>("");
const [editConstraint, setEditConstraint] = useState<string>("");
Expand Down
60 changes: 59 additions & 1 deletion src/constraints/constraint.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ResolveConstraint, ResolveConstraints } from "./constraint";
import { ComponentInstance, Side, ConstraintInstance } from "./definition";
import { ComponentInstance, Side, ConstraintInstance, WidthConstraintInstance, HeightConstraintInstance, RelativeConstraintInstance } from "./definition";

const ParentComponent = (): ComponentInstance => ({
name: "parent",
Expand Down Expand Up @@ -94,4 +94,62 @@ describe("constraint resolving tests", () => {
[Side.left]: 10
});
});

test("a simple width constraint", () => {
const testedComponent = NewComponent("nameX");
const parent = ParentComponent();
const constraintLeft: ConstraintInstance = {
fromInstance: testedComponent,
toInstance: parent,
resolved: Boolean(false),
fromSide: Side.left,
toSide: Side.left,
distance: 10
};

const widthConstraint: WidthConstraintInstance = {
instance: testedComponent,
resolved: Boolean(false),
width: 80
};

ResolveConstraints([
constraintLeft,
widthConstraint
]);

expect(testedComponent.positions).toStrictEqual({
[Side.right]: 90,
[Side.left]: 10
});
});

test("a simple height constraint", () => {
const testedComponent = NewComponent("nameX");
const parent = ParentComponent();
const constraintBottom: RelativeConstraintInstance = {
fromInstance: testedComponent,
toInstance: parent,
resolved: Boolean(false),
fromSide: Side.bottom,
toSide: Side.bottom,
distance: -25
};

const heightConstraint: HeightConstraintInstance = {
instance: testedComponent,
resolved: Boolean(false),
height: 40
};

ResolveConstraints([
constraintBottom,
heightConstraint
]);

expect(testedComponent.positions).toStrictEqual({
[Side.bottom]: 75,
[Side.top]: 35
});
});
});
50 changes: 48 additions & 2 deletions src/constraints/constraint.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ConstraintInstance, ConstraintInstances } from "./definition";
import { ConstraintInstance, ConstraintInstances, RelativeConstraintInstance, WidthConstraintInstance, Side, HeightConstraintInstance } from "./definition";

export const ResolveConstraint = (constraint: ConstraintInstance): void => {
const ResolveRelativeConstraint = (constraint: RelativeConstraintInstance): void => {
const {
fromInstance,
fromSide,
Expand All @@ -17,6 +17,52 @@ export const ResolveConstraint = (constraint: ConstraintInstance): void => {
}
};

const ResolveWidthConstraint = (constraint: WidthConstraintInstance): void => {
const {
instance,
width,
resolved
} = constraint;
if (resolved) return;
if (instance.positions[Side.left] !== undefined) {
instance.positions[Side.right] = instance.positions[Side.left]! + width
constraint.resolved = Boolean(true);
} else if (instance.positions[Side.right] !== undefined) {
instance.positions[Side.left] = instance.positions[Side.right]! - width
constraint.resolved = Boolean(true);
};
};


const ResolveHeightConstraint = (constraint: HeightConstraintInstance): void => {
const {
instance,
height,
resolved
} = constraint;
if (resolved) return;
if (instance.positions[Side.top] !== undefined) {
instance.positions[Side.bottom] = instance.positions[Side.top]! + height
constraint.resolved = Boolean(true);
} else if (instance.positions[Side.bottom] !== undefined) {
instance.positions[Side.top] = instance.positions[Side.bottom]! - height
constraint.resolved = Boolean(true);
};
};


export const ResolveConstraint = (constraint: ConstraintInstance): void => {
if (constraint.resolved) return;
const keys = Object.keys(constraint)
if (keys.includes("distance")) {
ResolveRelativeConstraint(constraint as RelativeConstraintInstance)
} else if (keys.includes("width")) {
ResolveWidthConstraint(constraint as WidthConstraintInstance)
} else if (keys.includes("height")) {
ResolveHeightConstraint(constraint as HeightConstraintInstance)
}
};

export const isConstraintResolved = (constraint: ConstraintInstance): Boolean =>
constraint.resolved;

Expand Down
17 changes: 16 additions & 1 deletion src/constraints/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum Side {
left = "left"
}


export interface ConstraintDefinition {
component: string;
fromSide: keyof typeof Side;
Expand All @@ -31,7 +32,19 @@ export interface ComponentInstance {

export type ComponentInstances = ComponentInstance[];

export interface ConstraintInstance {
export interface WidthConstraintInstance {
instance: ComponentInstance;
resolved: Boolean;
width: number;
};

export interface HeightConstraintInstance {
instance: ComponentInstance;
resolved: Boolean;
height: number;
};

export interface RelativeConstraintInstance {
fromInstance: ComponentInstance;
fromSide: Side;
toInstance: ComponentInstance;
Expand All @@ -40,4 +53,6 @@ export interface ConstraintInstance {
resolved: Boolean;
}

export type ConstraintInstance = RelativeConstraintInstance | WidthConstraintInstance | HeightConstraintInstance

export type ConstraintInstances = ConstraintInstance[];
14 changes: 14 additions & 0 deletions src/constraints/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ export const ParseLayout = (
resolved: Boolean(false)
})
);
if(component.width !== undefined){
constraints.push({
instance: findComponentByName(components, name),
width: component.width,
resolved: Boolean(false)
})
}
if(component.height !== undefined){
constraints.push({
instance: findComponentByName(components, name),
height: component.height,
resolved: Boolean(false)
})
}
}

return [components, constraints];
Expand Down
101 changes: 101 additions & 0 deletions src/examples/appLayout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { LayoutDefinition } from "../constraints/definition";

export const appLayout: LayoutDefinition = {
Sidebar: {
width:32*4,
constraints: [
{
component: "parent",
fromSide: "top",
toSide: "top",
distance: 32
},
{
component: "parent",
fromSide: "bottom",
toSide: "bottom",
distance: -32
},
{
component: "parent",
fromSide: "left",
toSide: "left",
distance: 32
}
]
},
Header: {
height:32*2,
constraints: [
{
component: "parent",
fromSide: "top",
toSide: "top",
distance: 32
},
{
component: "Sidebar",
fromSide: "left",
toSide: "right",
distance: 32
},
{
component: "parent",
fromSide: "right",
toSide: "right",
distance: -32
}
]
},
Footer: {
height:32,
constraints: [
{
component: "parent",
fromSide: "bottom",
toSide: "bottom",
distance: -32
},
{
component: "Sidebar",
fromSide: "left",
toSide: "right",
distance: 32
},
{
component: "parent",
fromSide: "right",
toSide: "right",
distance: -32
}
]
},
Content: {
constraints: [
{
component: "Header",
fromSide: "top",
toSide: "bottom",
distance: 32
},
{
component: "Footer",
fromSide: "bottom",
toSide: "top",
distance: -32
},
{
component: "Sidebar",
fromSide: "left",
toSide: "right",
distance: 32
},
{
component: "parent",
fromSide: "right",
toSide: "right",
distance: -32
}
]
}
};

0 comments on commit 69cef53

Please sign in to comment.