/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import { Align, BoxSizing, Direction, Display, Edge, FlexDirection, Gutter, Justify, Overflow, PositionType, Wrap, Node as YogaNode, } from 'yoga-layout'; export type AlignContent = | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'space-between' | 'space-around' | 'space-evenly'; export type AlignItems = | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'; export type JustifyContent = | 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'; export type FlexStyle = { alignContent?: AlignContent; alignItems?: AlignItems; alignSelf?: AlignItems; aspectRatio?: number; borderBottomWidth?: number; borderEndWidth?: number; borderLeftWidth?: number; borderRightWidth?: number; borderStartWidth?: number; borderTopWidth?: number; borderWidth?: number; borderInlineWidth?: number; borderBlockWidth?: number; bottom?: number | `${number}%`; boxSizing?: 'border-box' | 'content-box'; direction?: 'ltr' | 'rtl'; display?: 'none' | 'flex'; end?: number | `${number}%`; flex?: number; flexBasis?: number | 'auto' | `${number}%`; flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse'; rowGap?: number; gap?: number; columnGap?: number; flexGrow?: number; flexShrink?: number; flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse'; height?: number | 'auto' | `${number}%`; justifyContent?: JustifyContent; left?: number | `${number}%`; margin?: number | 'auto' | `${number}%`; marginBottom?: number | 'auto' | `${number}%`; marginEnd?: number | 'auto' | `${number}%`; marginLeft?: number | 'auto' | `${number}%`; marginRight?: number | 'auto' | `${number}%`; marginStart?: number | 'auto' | `${number}%`; marginTop?: number | 'auto' | `${number}%`; marginInline?: number | 'auto' | `${number}%`; marginBlock?: number | 'auto' | `${number}%`; maxHeight?: number | `${number}%`; maxWidth?: number | `${number}%`; minHeight?: number | `${number}%`; minWidth?: number | `${number}%`; overflow?: 'visible' | 'hidden' | 'scroll'; padding?: number | `${number}%`; paddingBottom?: number | `${number}%`; paddingEnd?: number | `${number}%`; paddingLeft?: number | `${number}%`; paddingRight?: number | `${number}%`; paddingStart?: number | `${number}%`; paddingTop?: number | `${number}%`; paddingInline?: number | `${number}%`; paddingBlock?: number | `${number}%`; position?: 'absolute' | 'relative' | 'static'; right?: number | `${number}%`; start?: number | `${number}%`; top?: number | `${number}%`; insetInline?: number | `${number}%`; insetBlock?: number | `${number}%`; inset?: number | `${number}%`; width?: number | 'auto' | `${number}%`; }; export function applyStyle(node: YogaNode, style: FlexStyle = {}): void { for (const key of Object.keys(style)) { try { switch (key) { case 'alignContent': node.setAlignContent(alignContent(style.alignContent)); break; case 'alignItems': node.setAlignItems(alignItems(style.alignItems)); break; case 'alignSelf': node.setAlignSelf(alignItems(style.alignSelf)); break; case 'aspectRatio': node.setAspectRatio(style.aspectRatio); break; case 'borderBottomWidth': node.setBorder(Edge.Bottom, style.borderBottomWidth); break; case 'borderEndWidth': node.setBorder(Edge.End, style.borderEndWidth); break; case 'borderLeftWidth': node.setBorder(Edge.Left, style.borderLeftWidth); break; case 'borderRightWidth': node.setBorder(Edge.Right, style.borderRightWidth); break; case 'borderStartWidth': node.setBorder(Edge.Start, style.borderStartWidth); break; case 'borderTopWidth': node.setBorder(Edge.Top, style.borderTopWidth); break; case 'borderWidth': node.setBorder(Edge.All, style.borderWidth); break; case 'borderInlineWidth': node.setBorder(Edge.Horizontal, style.borderInlineWidth); break; case 'borderBlockWidth': node.setBorder(Edge.Vertical, style.borderBlockWidth); break; case 'bottom': node.setPosition(Edge.Bottom, style.bottom); break; case 'boxSizing': node.setBoxSizing(boxSizing(style.boxSizing)); break; case 'direction': node.setDirection(direction(style.direction)); break; case 'display': node.setDisplay(display(style.display)); break; case 'end': node.setPosition(Edge.End, style.end); break; case 'flex': node.setFlex(style.flex); break; case 'flexBasis': node.setFlexBasis(style.flexBasis); break; case 'flexDirection': node.setFlexDirection(flexDirection(style.flexDirection)); break; case 'rowGap': node.setGap(Gutter.Row, style.rowGap); break; case 'gap': node.setGap(Gutter.All, style.gap); break; case 'columnGap': node.setGap(Gutter.Column, style.columnGap); break; case 'flexGrow': node.setFlexGrow(style.flexGrow); break; case 'flexShrink': node.setFlexShrink(style.flexShrink); break; case 'flexWrap': node.setFlexWrap(flexWrap(style.flexWrap)); break; case 'height': node.setHeight(style.height); break; case 'justifyContent': node.setJustifyContent(justifyContent(style.justifyContent)); break; case 'left': node.setPosition(Edge.Left, style.left); break; case 'margin': node.setMargin(Edge.All, style.margin); break; case 'marginBottom': node.setMargin(Edge.Bottom, style.marginBottom); break; case 'marginEnd': node.setMargin(Edge.End, style.marginEnd); break; case 'marginLeft': node.setMargin(Edge.Left, style.marginLeft); break; case 'marginRight': node.setMargin(Edge.Right, style.marginRight); break; case 'marginStart': node.setMargin(Edge.Start, style.marginStart); break; case 'marginTop': node.setMargin(Edge.Top, style.marginTop); break; case 'marginInline': node.setMargin(Edge.Horizontal, style.marginInline); break; case 'marginBlock': node.setMargin(Edge.Vertical, style.marginBlock); break; case 'maxHeight': node.setMaxHeight(style.maxHeight); break; case 'maxWidth': node.setMaxWidth(style.maxWidth); break; case 'minHeight': node.setMinHeight(style.minHeight); break; case 'minWidth': node.setMinWidth(style.minWidth); break; case 'overflow': node.setOverflow(overflow(style.overflow)); break; case 'padding': node.setPadding(Edge.All, style.padding); break; case 'paddingBottom': node.setPadding(Edge.Bottom, style.paddingBottom); break; case 'paddingEnd': node.setPadding(Edge.End, style.paddingEnd); break; case 'paddingLeft': node.setPadding(Edge.Left, style.paddingLeft); break; case 'paddingRight': node.setPadding(Edge.Right, style.paddingRight); break; case 'paddingStart': node.setPadding(Edge.Start, style.paddingStart); break; case 'paddingTop': node.setPadding(Edge.Top, style.paddingTop); break; case 'paddingInline': node.setPadding(Edge.Horizontal, style.paddingInline); break; case 'paddingBlock': node.setPadding(Edge.Vertical, style.paddingBlock); break; case 'position': node.setPositionType(position(style.position)); break; case 'right': node.setPosition(Edge.Right, style.right); break; case 'start': node.setPosition(Edge.Start, style.start); break; case 'top': node.setPosition(Edge.Top, style.top); break; case 'insetInline': node.setPosition(Edge.Horizontal, style.insetInline); break; case 'insetBlock': node.setPosition(Edge.Vertical, style.insetBlock); break; case 'inset': node.setPosition(Edge.All, style.inset); break; case 'width': node.setWidth(style.width); break; } } catch (e) { // Fail gracefully } } } function alignContent(str?: AlignContent): Align { switch (str) { case 'flex-start': return Align.FlexStart; case 'flex-end': return Align.FlexEnd; case 'center': return Align.Center; case 'stretch': return Align.Stretch; case 'space-between': return Align.SpaceBetween; case 'space-around': return Align.SpaceAround; case 'space-evenly': return Align.SpaceEvenly; } throw new Error(`"${str}" is not a valid value for alignContent`); } function alignItems(str?: AlignItems): Align { switch (str) { case 'flex-start': return Align.FlexStart; case 'flex-end': return Align.FlexEnd; case 'center': return Align.Center; case 'stretch': return Align.Stretch; case 'baseline': return Align.Baseline; } throw new Error(`"${str}" is not a valid value for alignItems`); } function boxSizing(str?: 'border-box' | 'content-box'): BoxSizing { switch (str) { case 'border-box': return BoxSizing.BorderBox; case 'content-box': return BoxSizing.ContentBox; } throw new Error(`"${str}" is not a valid value for boxSizing`); } function direction(str?: 'ltr' | 'rtl'): Direction { switch (str) { case 'ltr': return Direction.LTR; case 'rtl': return Direction.RTL; } throw new Error(`"${str}" is not a valid value for direction`); } function display(str?: 'none' | 'flex'): Display { switch (str) { case 'none': return Display.None; case 'flex': return Display.Flex; } throw new Error(`"${str}" is not a valid value for display`); } function flexDirection( str?: 'row' | 'column' | 'row-reverse' | 'column-reverse', ): FlexDirection { switch (str) { case 'row': return FlexDirection.Row; case 'column': return FlexDirection.Column; case 'row-reverse': return FlexDirection.RowReverse; case 'column-reverse': return FlexDirection.ColumnReverse; } throw new Error(`"${str}" is not a valid value for flexDirection`); } function flexWrap(str?: 'wrap' | 'nowrap' | 'wrap-reverse'): Wrap { switch (str) { case 'wrap': return Wrap.Wrap; case 'nowrap': return Wrap.NoWrap; case 'wrap-reverse': return Wrap.WrapReverse; } throw new Error(`"${str}" is not a valid value for flexWrap`); } function justifyContent(str?: JustifyContent): Justify { switch (str) { case 'flex-start': return Justify.FlexStart; case 'flex-end': return Justify.FlexEnd; case 'center': return Justify.Center; case 'space-between': return Justify.SpaceBetween; case 'space-around': return Justify.SpaceAround; case 'space-evenly': return Justify.SpaceEvenly; } throw new Error(`"${str}" is not a valid value for justifyContent`); } function overflow(str?: 'visible' | 'hidden' | 'scroll'): Overflow { switch (str) { case 'visible': return Overflow.Visible; case 'hidden': return Overflow.Hidden; case 'scroll': return Overflow.Scroll; } throw new Error(`"${str}" is not a valid value for overflow`); } function position(str?: 'absolute' | 'relative' | 'static'): PositionType { switch (str) { case 'absolute': return PositionType.Absolute; case 'relative': return PositionType.Relative; case 'static': return PositionType.Static; } throw new Error(`"${str}" is not a valid value for position`); }