Skip to content

Commit d32c26c

Browse files
committed
feat: add gap, aspectRatio, flex, direction and boxSizing to UiTransform
1 parent 0f012e0 commit d32c26c

25 files changed

Lines changed: 518 additions & 70 deletions

package-lock.json

Lines changed: 6 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"bugs": "https://github.com/decentraland/js-sdk-toolchain/issues",
77
"dependencies": {
88
"@actions/core": "^1.10.0",
9-
"@dcl/protocol": "1.0.0-30373157983.commit-2c475cb",
9+
"@dcl/protocol": "https://sdk-team-cdn.decentraland.org/@dcl/protocol/branch//dcl-protocol-1.0.0-31028775440.commit-ffd471e.tgz",
1010
"@dcl/quickjs-emscripten": "^0.21.0-3680274614.commit-1808aa1",
1111
"@dcl/ts-proto": "1.153.0",
1212
"@types/fs-extra": "^9.0.12",

packages/@dcl/playground-assets/etc/playground-assets.api.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ export namespace BorderRect {
299299
export function encode(message: BorderRect, writer?: _m0.Writer): _m0.Writer;
300300
}
301301

302+
// @public
303+
export type BoxSizingType = 'border-box' | 'content-box';
304+
302305
// Warning: (tsdoc-undefined-tag) The TSDoc tag "@category" is not defined in this configuration
303306
//
304307
// @public
@@ -1060,6 +1063,9 @@ export type DeleteEntityNetworkMessageBody = {
10601063
networkId: number;
10611064
};
10621065

1066+
// @public
1067+
export type DirectionType = 'inherit' | 'ltr' | 'rtl';
1068+
10631069
// @public (undocumented)
10641070
export type DisplayType = 'flex' | 'none';
10651071

@@ -1316,6 +1322,9 @@ export const enum Font {
13161322
F_SERIF = 1
13171323
}
13181324

1325+
// @public
1326+
export type GapShorthand = PositionUnit | `${PositionUnit} ${PositionUnit}`;
1327+
13191328
// @public
13201329
export function getComponentEntityTree<T>(engine: Pick<IEngine, 'getEntitiesWith'>, entity: Entity, component: ComponentDefinition<T & {
13211330
parent?: Entity;
@@ -3913,6 +3922,7 @@ export interface PBUiTransform {
39133922
alignContent?: YGAlign | undefined;
39143923
alignItems?: YGAlign | undefined;
39153924
alignSelf: YGAlign;
3925+
aspectRatio?: number | undefined;
39163926
// (undocumented)
39173927
borderBottomColor?: PBColor4 | undefined;
39183928
// (undocumented)
@@ -3944,7 +3954,13 @@ export interface PBUiTransform {
39443954
// (undocumented)
39453955
borderTopWidth?: number | undefined;
39463956
borderTopWidthUnit?: YGUnit | undefined;
3957+
boxSizing?: YGBoxSizing | undefined;
3958+
// (undocumented)
3959+
columnGap?: number | undefined;
3960+
columnGapUnit?: YGUnit | undefined;
3961+
direction?: YGDirection | undefined;
39473962
display: YGDisplay;
3963+
flex?: number | undefined;
39483964
// (undocumented)
39493965
flexBasis: number;
39503966
flexBasisUnit: YGUnit;
@@ -3954,6 +3970,9 @@ export interface PBUiTransform {
39543970
flexShrink?: number | undefined;
39553971
flexWrap?: YGWrap | undefined;
39563972
// (undocumented)
3973+
gap?: number | undefined;
3974+
gapUnit?: YGUnit | undefined;
3975+
// (undocumented)
39573976
height: number;
39583977
heightUnit: YGUnit;
39593978
justifyContent: YGJustify;
@@ -4014,6 +4033,9 @@ export interface PBUiTransform {
40144033
// (undocumented)
40154034
rightOf: number;
40164035
// (undocumented)
4036+
rowGap?: number | undefined;
4037+
rowGapUnit?: YGUnit | undefined;
4038+
// (undocumented)
40174039
width: number;
40184040
widthUnit: YGUnit;
40194041
zIndex?: number | undefined;
@@ -5435,19 +5457,24 @@ export interface UiTransformProps {
54355457
alignContent?: AlignType;
54365458
alignItems?: AlignType;
54375459
alignSelf?: AlignType;
5460+
aspectRatio?: number;
54385461
// (undocumented)
54395462
borderColor?: Record<keyof Partial<Position>, PBColor4> | PBColor4 | undefined;
54405463
// (undocumented)
54415464
borderRadius?: Partial<BorderRadius> | PositionUnit;
54425465
// (undocumented)
54435466
borderWidth?: Partial<Position> | PositionUnit;
5467+
boxSizing?: BoxSizingType;
5468+
columnGap?: PositionUnit;
5469+
direction?: DirectionType;
54445470
display?: DisplayType;
54455471
flex?: number;
54465472
flexBasis?: number;
54475473
flexDirection?: FlexDirectionType;
54485474
flexGrow?: number;
54495475
flexShrink?: number;
54505476
flexWrap?: FlexWrapType;
5477+
gap?: GapShorthand;
54515478
height?: PositionUnit | 'auto';
54525479
justifyContent?: JustifyType;
54535480
margin?: Partial<Position> | PositionShorthand;
@@ -5461,6 +5488,7 @@ export interface UiTransformProps {
54615488
pointerFilter?: PointerFilterType;
54625489
position?: Partial<Position> | PositionShorthand;
54635490
positionType?: PositionType;
5491+
rowGap?: PositionUnit;
54645492
width?: PositionUnit | 'auto';
54655493
zIndex?: number;
54665494
}
@@ -5693,6 +5721,24 @@ export const enum YGAlign {
56935721
YGA_STRETCH = 4
56945722
}
56955723

5724+
// @public (undocumented)
5725+
export const enum YGBoxSizing {
5726+
// (undocumented)
5727+
YGBS_BORDER_BOX = 0,
5728+
// (undocumented)
5729+
YGBS_CONTENT_BOX = 1
5730+
}
5731+
5732+
// @public (undocumented)
5733+
export const enum YGDirection {
5734+
// (undocumented)
5735+
YGDIR_INHERIT = 0,
5736+
// (undocumented)
5737+
YGDIR_LTR = 1,
5738+
// (undocumented)
5739+
YGDIR_RTL = 2
5740+
}
5741+
56965742
// @public (undocumented)
56975743
export const enum YGDisplay {
56985744
// (undocumented)

packages/@dcl/react-ecs/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ The layout system is based on Flexbox and supports the following properties:
100100
- `width`, `height`
101101
- `margin`, `padding`
102102
- `positionType: 'absolute' | 'relative'`
103+
- `gap`, `rowGap`, `columnGap`
104+
- `flex`, `aspectRatio`
105+
- `direction: 'inherit' | 'ltr' | 'rtl'`
106+
- `boxSizing: 'border-box' | 'content-box'`
103107

104108
## Event Handling
105109

packages/@dcl/react-ecs/src/components/uiTransform/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {
22
getAlign,
3+
getBoxSizing,
4+
getDirection,
35
getDisplay,
46
getFlexDirection,
57
getFlexWrap,
@@ -10,6 +12,7 @@ import {
1012
parseBorderColor,
1113
parseBorderRadius,
1214
parseBorderWidth,
15+
parseGap,
1316
parsePosition,
1417
parseSize
1518
} from './utils'
@@ -102,12 +105,18 @@ export function parseUiTransform(props: UiTransformProps = {}): PBUiTransform {
102105
borderRadius,
103106
borderWidth,
104107
borderColor,
108+
gap,
109+
rowGap,
110+
columnGap,
111+
direction,
112+
boxSizing,
105113
...otherProps
106114
} = props
107115

108116
return {
109117
...defaultUiTransform,
110118
...otherProps,
119+
...parseGap(gap, rowGap, columnGap),
111120
...parsePosition(props.position, 'position'),
112121
...parsePosition(props.margin, 'margin'),
113122
...parsePosition(props.padding, 'padding'),
@@ -130,6 +139,8 @@ export function parseUiTransform(props: UiTransformProps = {}): PBUiTransform {
130139
...(flexWrap && getFlexWrap(flexWrap)),
131140
...(borderRadius && parseBorderRadius(borderRadius)),
132141
...(borderWidth && parseBorderWidth(borderWidth)),
133-
...(borderColor && parseBorderColor(borderColor))
142+
...(borderColor && parseBorderColor(borderColor)),
143+
...(direction && getDirection(direction)),
144+
...(boxSizing && getBoxSizing(boxSizing))
134145
}
135146
}

packages/@dcl/react-ecs/src/components/uiTransform/types.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,32 @@ export type PositionType = 'absolute' | 'relative'
9595
*/
9696
export type PointerFilterType = 'none' | 'block'
9797

98+
/**
99+
* @public
100+
* The direction property specifies the layout direction of the element (left-to-right or right-to-left)
101+
*/
102+
export type DirectionType = 'inherit' | 'ltr' | 'rtl'
103+
104+
/**
105+
* @public
106+
* The box-sizing property defines whether width/height include padding and border (border-box) or only the content (content-box)
107+
*/
108+
export type BoxSizingType = 'border-box' | 'content-box'
109+
110+
/**
111+
* The gap shorthand: one value applies to both axes; two space-separated values apply to row then column
112+
* @public
113+
*/
114+
export type GapShorthand = PositionUnit | `${PositionUnit} ${PositionUnit}`
115+
98116
/**
99117
* Layout props to position things in the canvas
100118
* @public
101119
*/
102120
export interface UiTransformProps {
103121
/** The display property controls if a item is going to be displayed or not. */
104122
display?: DisplayType
105-
/** The flex shorthand property sets how a flex item will grow or shrink to fit the space available in its flex container. */
123+
/** The flex shorthand property sets how a flex item will grow or shrink to fit the space available in its flex container. It sets flex-grow, flex-shrink and flex-basis following Yoga semantics. */
106124
flex?: number
107125
/** Justify content describes how to align children within the main axis of their container. */
108126
justifyContent?: JustifyType
@@ -155,4 +173,16 @@ export interface UiTransformProps {
155173
opacity?: number
156174
/** default 0 */
157175
zIndex?: number
176+
/** The gap shorthand sets the spacing between rows and columns of a flex container. One value applies to both axes; two space-separated values apply to row then column. */
177+
gap?: GapShorthand
178+
/** The row-gap property sets the spacing between the rows of a flex container. Takes precedence over gap on its axis. */
179+
rowGap?: PositionUnit
180+
/** The column-gap property sets the spacing between the columns of a flex container. Takes precedence over gap on its axis. */
181+
columnGap?: PositionUnit
182+
/** The aspect-ratio property locks the element's width / height ratio. */
183+
aspectRatio?: number
184+
/** The direction property specifies the layout direction of the element @defaultValue 'inherit' */
185+
direction?: DirectionType
186+
/** The box-sizing property defines whether width/height include padding and border @defaultValue 'border-box' */
187+
boxSizing?: BoxSizingType
158188
}

packages/@dcl/react-ecs/src/components/uiTransform/utils.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {
22
YGAlign,
3+
YGBoxSizing,
4+
YGDirection,
35
YGDisplay,
46
YGFlexDirection,
57
YGJustify,
@@ -11,9 +13,12 @@ import {
1113
} from '@dcl/ecs'
1214
import {
1315
AlignType,
16+
BoxSizingType,
17+
DirectionType,
1418
FlexDirectionType,
1519
DisplayType,
1620
FlexWrapType,
21+
GapShorthand,
1722
JustifyType,
1823
OverflowType,
1924
Position,
@@ -213,6 +218,49 @@ export function parsePosition<T extends PropName>(
213218
return parsePosition({ top, right, bottom, left }, prop)
214219
}
215220

221+
type GapProp = 'gap' | 'rowGap' | 'columnGap'
222+
type GapPropUnit = `${GapProp}Unit`
223+
type GapProps = {
224+
[key in GapProp]?: number
225+
} & {
226+
[key in GapPropUnit]?: YGUnit
227+
}
228+
/**
229+
* @internal
230+
*/
231+
export function parseGap(
232+
gap: GapShorthand | undefined,
233+
rowGap: PositionUnit | undefined,
234+
columnGap: PositionUnit | undefined
235+
): Partial<GapProps> {
236+
const obj: Partial<GapProps> = {}
237+
238+
function setGap(prop: GapProp, val: PositionUnit | undefined) {
239+
const [value, unit] = parsePositionUnit(val)
240+
if (value === undefined) return
241+
obj[prop] = value
242+
obj[`${prop}Unit`] = unit
243+
}
244+
245+
if (typeof gap === 'string') {
246+
const values = gap.split(' ').filter((a) => a !== '') as PositionUnit[]
247+
if (values.length >= 2) {
248+
setGap('rowGap', values[0])
249+
setGap('columnGap', values[1])
250+
} else {
251+
setGap('gap', values[0])
252+
}
253+
} else {
254+
setGap('gap', gap)
255+
}
256+
257+
// longhands win over the shorthand; Yoga resolves row/column precedence over the all-gutter
258+
setGap('rowGap', rowGap)
259+
setGap('columnGap', columnGap)
260+
261+
return obj
262+
}
263+
216264
// Size Props
217265
type HeightWidth = 'height' | 'width'
218266
type SizePropName = HeightWidth | `max${Capitalize<HeightWidth>}` | `min${Capitalize<HeightWidth>}`
@@ -351,3 +399,28 @@ const parsePointerFilter: Readonly<Record<PointerFilterType, PointerFilterMode>>
351399
none: PointerFilterMode.PFM_NONE,
352400
block: PointerFilterMode.PFM_BLOCK
353401
}
402+
403+
/**
404+
* @internal
405+
*/
406+
export function getDirection(direction: DirectionType): Record<'direction', YGDirection> {
407+
return { direction: parseDirection[direction] }
408+
}
409+
410+
const parseDirection: Readonly<Record<DirectionType, YGDirection>> = {
411+
inherit: YGDirection.YGDIR_INHERIT,
412+
ltr: YGDirection.YGDIR_LTR,
413+
rtl: YGDirection.YGDIR_RTL
414+
}
415+
416+
/**
417+
* @internal
418+
*/
419+
export function getBoxSizing(boxSizing: BoxSizingType): Record<'boxSizing', YGBoxSizing> {
420+
return { boxSizing: parseBoxSizing[boxSizing] }
421+
}
422+
423+
const parseBoxSizing: Readonly<Record<BoxSizingType, YGBoxSizing>> = {
424+
'border-box': YGBoxSizing.YGBS_BORDER_BOX,
425+
'content-box': YGBoxSizing.YGBS_CONTENT_BOX
426+
}

0 commit comments

Comments
 (0)