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
145 lines
4.4 KiB
JavaScript
145 lines
4.4 KiB
JavaScript
// @flow
|
|
import yoga from 'yoga-layout';
|
|
import LayoutRecord from './LayoutRecord';
|
|
import PositionRecord from './PositionRecord';
|
|
import type {LayoutRecordT} from './LayoutRecord';
|
|
import type {Yoga$Direction} from 'yoga-layout';
|
|
|
|
const enumLookup = {
|
|
flexDirection: {
|
|
[yoga.FLEX_DIRECTION_COLUMN]: 'CKFlexboxDirectionVertical',
|
|
[yoga.FLEX_DIRECTION_ROW]: 'CKFlexboxDirectionHorizontal',
|
|
[yoga.FLEX_DIRECTION_COLUMN_REVERSE]: 'CKFlexboxDirectionVerticalReverse',
|
|
[yoga.FLEX_DIRECTION_ROW_REVERSE]: 'CKFlexboxDirectionHorizontalReverse',
|
|
},
|
|
alignItems: {
|
|
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignItemsStart',
|
|
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignItemsEnd',
|
|
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignItemsCenter',
|
|
[yoga.ALIGN_BASELINE]: 'CKFlexboxAlignItemsBaseline',
|
|
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignItemsStretch',
|
|
},
|
|
alignSelf: {
|
|
[yoga.ALIGN_AUTO]: 'CKFlexboxAlignSelfAuto',
|
|
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignSelfStart',
|
|
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignSelfEnd',
|
|
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignSelfCenter',
|
|
[yoga.ALIGN_BASELINE]: 'CKFlexboxAlignSelfBaseline',
|
|
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignSelfStretch',
|
|
},
|
|
alignContent: {
|
|
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignContentStart',
|
|
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignContentEnd',
|
|
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignContentCenter',
|
|
[yoga.ALIGN_SPACE_BETWEEN]: 'CKFlexboxAlignContentSpaceBetween',
|
|
[yoga.ALIGN_SPACE_AROUND]: 'CKFlexboxAlignContentSpaceAround',
|
|
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignContentStretch',
|
|
},
|
|
justifyContent: {
|
|
[yoga.JUSTIFY_FLEX_START]: 'CKFlexboxJustifyContentStart',
|
|
[yoga.JUSTIFY_CENTER]: 'CKFlexboxJustifyContentCenter',
|
|
[yoga.JUSTIFY_FLEX_END]: 'CKFlexboxJustifyContentEnd',
|
|
[yoga.JUSTIFY_SPACE_BETWEEN]: 'CKFlexboxJustifyContentSpaceBetween',
|
|
[yoga.JUSTIFY_SPACE_AROUND]: 'CKFlexboxJustifyContentSpaceAround',
|
|
},
|
|
flexWrap: {
|
|
[yoga.WRAP_NO_WRAP]: 'CKFlexboxWrapNoWrap',
|
|
[yoga.WRAP_WRAP]: 'CKFlexboxWrapWrap',
|
|
[yoga.WRAP_WRAP_REVERSE]: 'CKFlexboxWrapWrapReverse',
|
|
},
|
|
positionType: {
|
|
[yoga.POSITION_TYPE_RELATIVE]: 'CKFlexboxPositionTypeRelative',
|
|
[yoga.POSITION_TYPE_ABSOLUTE]: 'CKFlexboxPositionTypeAbsolute',
|
|
},
|
|
};
|
|
|
|
function keyLookup(key: string): string {
|
|
const keyLookup = {
|
|
flexWrap: 'wrap',
|
|
flexDirection: 'direction',
|
|
};
|
|
return keyLookup[key] || key;
|
|
}
|
|
|
|
function getLayoutCode(
|
|
node: LayoutRecordT,
|
|
indent: string = '',
|
|
isRoot?: boolean,
|
|
): string {
|
|
const lines = [];
|
|
|
|
lines.push(indent + `[CKFlexboxComponent`);
|
|
lines.push(indent + ` newWithView:kWhiteBackgroundView`);
|
|
lines.push(indent + ` size:{${node.width},${node.height}}`);
|
|
lines.push(indent + ` style:{`);
|
|
const untouchedLayout = LayoutRecord({});
|
|
const untouchedPosition = PositionRecord({});
|
|
|
|
Object.keys(node.toJSON()).forEach(key => {
|
|
if (
|
|
node[key] instanceof PositionRecord &&
|
|
!node[key].equals(untouchedPosition)
|
|
) {
|
|
lines.push(indent + `\t.${key} = {`);
|
|
|
|
if (key === 'positionType') {
|
|
lines.push(
|
|
indent +
|
|
`\t.position = ${enumLookup.positionType[node.positionType]},`,
|
|
);
|
|
}
|
|
|
|
['top', 'left', 'right', 'bottom'].forEach(pKey => {
|
|
if (node[key][pKey]) {
|
|
lines.push(indent + `\t\t.${pKey} = ${node[key][pKey]},`);
|
|
}
|
|
});
|
|
|
|
lines.push(indent + `\t},`);
|
|
} else if (
|
|
key !== 'children' &&
|
|
key !== 'width' &&
|
|
key !== 'height' &&
|
|
node[key] !== untouchedLayout[key]
|
|
) {
|
|
if (enumLookup[key]) {
|
|
lines.push(
|
|
indent +
|
|
`\t.${keyLookup(key)} = ${enumLookup[key][node.flexDirection]},`,
|
|
);
|
|
} else {
|
|
console.error(`Unknown property ${key}`);
|
|
}
|
|
}
|
|
});
|
|
lines.push(indent + ` }`);
|
|
|
|
if (node.children.size > 0) {
|
|
lines.push(indent + ' children:{');
|
|
lines.push(
|
|
...node.children
|
|
.toJSON()
|
|
.map(
|
|
child =>
|
|
`${indent}\t{\n${getLayoutCode(
|
|
child,
|
|
indent + '\t\t',
|
|
)}\n${indent}\t},`,
|
|
),
|
|
);
|
|
lines.push(indent + '}');
|
|
}
|
|
lines[lines.length - 1] += `]${isRoot ? ';' : ''}`;
|
|
|
|
return lines.join('\n');
|
|
}
|
|
|
|
export default function generateCode(
|
|
root: LayoutRecordT,
|
|
direction: Yoga$Direction,
|
|
): string {
|
|
return ['CKFlexboxComponent *c =', getLayoutCode(root, '\t', true)].join(
|
|
'\n',
|
|
);
|
|
}
|