Files
yoga/playground/src/CodeLitho.js
Daniel Büchele 9718c517d9 add playground
Summary:
This adds a web-based playground to try out Yoga. The playground uses yogas javascript bindings to use yoga within the browser. The layout tree can be modified and shared. Code generators for litho, ComponentKit and React Native allow the layout to be copied into any app.

allow-large-files

Reviewed By: emilsjolander

Differential Revision: D6871601

fbshipit-source-id: 3b97c87e91d6bafe8e1c38b8b7eca8d372324c0b
2018-02-05 07:11:57 -08:00

162 lines
4.4 KiB
JavaScript

// @flow
import yoga from 'yoga-layout';
import LayoutRecord from './LayoutRecord';
import PositionRecord from './PositionRecord';
import {JSEnumLookup} from './CodeJavaScript';
import type {LayoutRecordT} from './LayoutRecord';
import type {Yoga$Direction} from 'yoga-layout';
function getEnum(yogaEnum: string, value: string | number): string {
const enumLookup = {
justifyContent: 'Justify',
alignItems: 'Align',
alignContent: 'Align',
alignSelf: 'Align',
position: 'Position',
flexWrap: 'Wrap',
positionType: 'PositionType',
direction: 'Driection',
};
if (!enumLookup[yogaEnum]) {
return String(value);
} else {
const enumValue = Object.keys(yoga)
.filter(key =>
key.toLowerCase().startsWith(JSEnumLookup[yogaEnum].toLowerCase()),
)
.find(key => yoga[key] === value);
return `Yoga${enumLookup[yogaEnum]}.${
enumValue ? enumValue.replace(/^([A-Z]+)_/, '') : value
}`;
}
}
function getLayoutCode(
node: LayoutRecordT,
indent: string = '',
isReturning?: boolean,
): string {
const lines = [];
const flexDirection = {
[yoga.FLEX_DIRECTION_ROW]: 'Row',
[yoga.FLEX_DIRECTION_ROW_REVERSE]: 'RowReverse',
[yoga.FLEX_DIRECTION_COLUMN]: 'Column',
[yoga.FLEX_DIRECTION_COLUMN_REVERSE]: 'ColumnReverse',
};
lines.push(
indent +
`${isReturning ? 'return ' : ''}${
flexDirection[node.flexDirection]
}.create(c)`,
);
if (node.children.size > 0) {
lines.push(
...node.children
.toJSON()
.map(
child =>
`${indent}\t.child(\n${getLayoutCode(child, indent + '\t\t')})`,
),
);
}
const untouchedLayout = LayoutRecord({width: '', height: ''});
const untouchedPosition = PositionRecord({});
Object.keys(node.toJSON()).forEach(key => {
if (
node[key] instanceof PositionRecord &&
!node[key].equals(untouchedPosition)
) {
if (key === 'border') {
lines.push(indent + '\t.border(', indent + '\t\tBorder.create(c)');
}
const {top, left, right, bottom} = node[key].toJS();
if (
top !== untouchedPosition.top &&
top === left &&
top === right &&
top === bottom
) {
// all edges
lines.push(
indent +
(key === 'border'
? `\t\t\t.widthDip(YogaEdge.ALL, ${node[key].top})`
: `\t.${key}Dip(YogaEdge.ALL, ${node[key].top})`),
);
return;
}
const alreadySet = [];
if (top !== untouchedPosition.top && top === bottom) {
lines.push(
indent +
(key === 'border'
? `\t\t\t.widthDip(YogaEdge.VERTICAL, ${node[key].top})`
: `\t.${key}Dip(YogaEdge.VERTICAL, ${node[key].top})`),
);
alreadySet.push('top', 'bottom');
}
if (left !== untouchedPosition.left && left === right) {
lines.push(
indent +
(key === 'border'
? `\t\t\t.widthDip(YogaEdge.HORIZONTAL, ${node[key].left})`
: `\t.${key}Dip(YogaEdge.HORIZONTAL, ${node[key].left})`),
);
alreadySet.push('left', 'right');
}
['left', 'top', 'right', 'bottom'].forEach((pKey, i) => {
if (
node[key][pKey] !== untouchedPosition[pKey] &&
alreadySet.indexOf(pKey) === -1
) {
lines.push(
indent +
(key === 'border'
? `\t\t\t.widthDip(YogaEdge.${pKey.toUpperCase()}, ${
node.border[pKey]
})`
: `\t.${key}Dip(YogaEdge.${pKey.toUpperCase()}, ${
node[key][pKey]
})`),
);
}
});
if (key === 'border') {
lines.push(
indent + '\t\t\t.color(YogaEdge.ALL, 0xfff36b7f)',
indent + '\t\t\t.build())',
);
}
} else if (
key !== 'children' &&
key !== 'flexDirection' &&
node[key] !== untouchedLayout[key]
) {
lines.push(indent + `\t.${key}(${getEnum(key, node[key])})`);
}
});
return lines.join('\n');
}
export default function generateCode(
root: LayoutRecordT,
direction: Yoga$Direction,
): string {
return [
'@LayoutSpec',
'public class PlaygroundComponentSpec {',
'\t@OnCreateLayout',
'\tstatic Component onCreateLayout(ComponentContext c) {',
getLayoutCode(root, '\t\t', true),
'\t\t\t.build();',
'\t}',
'}',
].join('\n');
}