Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support flexWrap in Box #479

Merged
merged 8 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,30 @@ See [flex-direction](https://css-tricks.com/almanac/properties/f/flex-direction/
// X
```

##### flexWrap

Type: `string`\
Allowed values: `nowrap` `wrap` `wrap-reverse`

See [flex-wrap](https://css-tricks.com/almanac/properties/f/flex-wrap/).

```jsx
<Box flexDirection="row" width={2} flexWrap="wrap">
<Text>A</Text>
<Text>BC</Text>
</Box>
// A
// B C

<Box flexDirection="column" height={2} flexWrap="wrap">
<Text>A</Text>
<Text>B</Text>
<Text>C</Text>
</Box>
// A C
// B
```

##### alignItems

Type: `string`\
Expand Down
1 change: 1 addition & 0 deletions src/components/Box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const Box = forwardRef<DOMElement, PropsWithChildren<Props>>(
Box.displayName = 'Box';

Box.defaultProps = {
flexWrap: 'nowrap',
flexDirection: 'row',
flexGrow: 0,
flexShrink: 1
Expand Down
16 changes: 16 additions & 0 deletions src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ export interface Styles {
*/
readonly flexBasis?: number | string;

/**
* It defines whether the flex items are forced in a single line or can be flowed into multiple lines. If set to multiple lines, it also defines the cross-axis which determines the direction new lines are stacked in.
* See [flex-wrap](https://css-tricks.com/almanac/properties/f/flex-wrap/).
*/
readonly flexWrap?: 'nowrap' | 'wrap' | 'wrap-reverse';

/**
* The align-items property defines the default behavior for how items are laid out along the cross axis (perpendicular to the main axis).
* See [align-items](https://css-tricks.com/almanac/properties/a/align-items/).
Expand Down Expand Up @@ -200,6 +206,16 @@ const applyFlexStyles = (node: YogaNode, style: Styles): void => {
);
}

if ('flexWrap' in style) {
if (style.flexWrap === 'nowrap') {
node.setFlexWrap(Yoga.WRAP_NO_WRAP);
} else if (style.flexWrap === 'wrap') {
jodevsa marked this conversation as resolved.
Show resolved Hide resolved
node.setFlexWrap(Yoga.WRAP_WRAP);
} else if (style.flexWrap === 'wrap-reverse') {
node.setFlexWrap(Yoga.WRAP_WRAP_REVERSE);
}
}

if ('flexDirection' in style) {
if (style.flexDirection === 'row') {
node.setFlexDirection(Yoga.FLEX_DIRECTION_ROW);
Expand Down
74 changes: 74 additions & 0 deletions test/flex-wrap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import test from 'ava';
import {renderToString} from './helpers/render-to-string';
import {Box, Text} from '../src';

test('row - no wrap', t => {
const output = renderToString(
<Box flexDirection="row" width={2}>
<Text>A</Text>
<Text>BC</Text>
</Box>
);

t.is(output, 'BC\n');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it expected that there's no A here?

Copy link
Contributor Author

@jodevsa jodevsa Oct 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really, by default overflow is expected to be visible in flex-box layout. this can be seen with plain Yoga:
https://replit.com/@SubhiAl/MonumentalNegligibleTrust#index.js

I needed to add the test to show the difference. The behaviour was there even before my changes.

Copy link
Contributor Author

@jodevsa jodevsa Oct 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that this is behaviour is caused by applying flexShrink=1 on each text node:
https://github.com/vadimdemedes/ink/blob/master/src/components/Text.tsx#L114

Changing flexShrink to 0 makes 'A' visible in the output

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was also able to reproduce the behaviour in plain Yoga:

https://replit.com/@SubhiAl/AwfulThreadbareMicroinstruction#index.js

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vadimdemedes sorry to spam you, but can this be merged?

});

test('column - no wrap', t => {
const output = renderToString(
<Box flexDirection="column" height={2}>
<Text>A</Text>
<Text>B</Text>
<Text>C</Text>
</Box>
);

t.is(output, 'B\nC');
jodevsa marked this conversation as resolved.
Show resolved Hide resolved
});

test('row - wrap content', t => {
const output = renderToString(
<Box flexDirection="row" width={2} flexWrap="wrap">
<Text>A</Text>
<Text>BC</Text>
</Box>
);

t.is(output, 'A\nBC');
});

test('column - wrap content', t => {
const output = renderToString(
<Box flexDirection="column" height={2} flexWrap="wrap">
<Text>A</Text>
<Text>B</Text>
<Text>C</Text>
</Box>
);

t.is(output, 'AC\nB');
});

test('column - wrap content reverse', t => {
const output = renderToString(
<Box flexDirection="column" height={2} width={3} flexWrap="wrap-reverse">
<Text>A</Text>
<Text>B</Text>
<Text>C</Text>
</Box>
);

t.is(output, ' CA\n B');
});

test('row - wrap content reverse', t => {
const output = renderToString(
<Box flexDirection="row" height={3} width={2} flexWrap="wrap-reverse">
<Text>A</Text>
<Text>B</Text>
<Text>C</Text>
</Box>
);

t.is(output, '\nC\nAB');
});