Skip to content

Commit

Permalink
feat: simple constraint resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianCraig committed Feb 25, 2020
1 parent 0f0d5f0 commit c0c651f
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 189 deletions.
4 changes: 4 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link
href="https://fonts.googleapis.com/css?family=Roboto+Mono:300&display=swap"
rel="stylesheet"
/>
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
Expand Down
53 changes: 33 additions & 20 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
import React from "react";
import "./App.css";
import { simpleBlock } from "./constraints/example";
import { createLayoutComponent } from "./constraints/generator";

const codeStyle: React.CSSProperties = {
width: "50vw",
height: "100vh",
padding: "10px",
boxSizing: "border-box",
position: "absolute",
whiteSpace: "pre-wrap"
};

const viewStyle: React.CSSProperties = {
width: "50vw",
height: "100vh",
padding: "10px",
boxSizing: "border-box",
position: "absolute",
left: "50%"
};

const Comp = createLayoutComponent(simpleBlock);

const App: React.FC = () => {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
<>
<div style={codeStyle} contentEditable>
{JSON.stringify(simpleBlock, null, 2)}
</div>
<div style={viewStyle}>
<Comp width={400} height={400} Block={<p>Hola</p>} />
</div>
</>
);
}
};

export default App;
19 changes: 19 additions & 0 deletions src/constraints/definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export type ConstraintSize = number;

export type ConstraintSide = "top" | "right" | "bottom" | "left";

export interface ConstraintDefinition {
component: string;
side: ConstraintSide;
distance: ConstraintSize;
}

export interface ConstraintComponent {
constraints: ConstraintDefinition[];
width?: ConstraintSize;
height?: ConstraintSize;
}

export interface ConstraintLayout {
[key: string]: ConstraintComponent;
}
28 changes: 28 additions & 0 deletions src/constraints/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ConstraintLayout } from "./definition";

export const simpleBlock: ConstraintLayout = {
Block: {
constraints: [
{
component: "parent",
side: "top",
distance: 32
},
{
component: "parent",
side: "right",
distance: 32
},
{
component: "parent",
side: "bottom",
distance: 32
},
{
component: "parent",
side: "left",
distance: 32
}
]
}
};
81 changes: 81 additions & 0 deletions src/constraints/generator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from "react";
import { ConstraintLayout, ConstraintComponent } from "./definition";

export interface LayoutComponent {
width: number;
height: number;
[key: string]: React.ReactNode;
}

enum Side {
top = "top",
right = "right",
bottom = "bottom",
left = "left"
}

class LayoutInstance {
private layoutInstanceList: LayoutInstance[];
private name: string;
private constraint: ConstraintComponent;
private resolvedPositions: { [key in Side]?: number } = {};

constructor(
layoutInstanceList: LayoutInstance[],
name: string,
constraint: ConstraintComponent
) {
this.layoutInstanceList = layoutInstanceList;
this.name = name;
this.constraint = constraint;
}

isThis = (name: string) => name === this.name;

resolve = (side: Side, position: number) =>
(this.resolvedPositions[side] = position);

isResolved = () => false;

toNode = () => (
<div
style={{
position: "absolute",
background: "#fafafa33",
width: this.constraint.width,
height: this.constraint.height,
...this.resolvedPositions
}}
/>
);
}

export const createLayoutComponent = (
options: ConstraintLayout
): React.FunctionComponent<LayoutComponent> => ({
width,
height,
...components
}) => {
const layoutInstanceList: LayoutInstance[] = [];
const parent = new LayoutInstance(layoutInstanceList, "parent", {
height,
width,
constraints: []
});

parent.resolve(Side.top, 0);
parent.resolve(Side.right, width);
parent.resolve(Side.bottom, height);
parent.resolve(Side.left, 0);

layoutInstanceList.push(parent);

for (const [name, constraint] of Object.entries(options)) {
layoutInstanceList.push(
new LayoutInstance(layoutInstanceList, name, constraint)
);
}

return <div>{layoutInstanceList.map(instance => instance.toNode())}</div>;
};
10 changes: 4 additions & 6 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
font-family: "Roboto Mono", monospace;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: darkviolet;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
* {
color: white;
}
16 changes: 5 additions & 11 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
ReactDOM.render(<App />, document.getElementById("root"));
7 changes: 0 additions & 7 deletions src/logo.svg

This file was deleted.

145 changes: 0 additions & 145 deletions src/serviceWorker.ts

This file was deleted.

0 comments on commit c0c651f

Please sign in to comment.