Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .changeset/chilled-pumas-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@react-pdf/layout": minor
---

feat: support percentage gap
23 changes: 3 additions & 20 deletions packages/layout/src/node/setGap.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,19 @@
import * as Yoga from 'yoga-layout/load';
import { isNil } from '@react-pdf/fns';

import { SafeNode } from '../types';
import setYogaValue from './setYogaValue';

/**
* Set rowGap value to node's Yoga instance
*
* @param value - Gap value
* @returns Node instance wrapper
*/
export const setRowGap = (value: number) => (node: SafeNode) => {
const { yogaNode } = node;

if (!isNil(value) && yogaNode) {
yogaNode.setGap(Yoga.Gutter.Row, value);
}

return node;
};
export const setRowGap = setYogaValue('gap', Yoga.Gutter.Row);

/**
* Set columnGap value to node's Yoga instance
*
* @param value - Gap value
* @returns Node instance wrapper
*/
export const setColumnGap = (value: number) => (node: SafeNode) => {
const { yogaNode } = node;

if (!isNil(value) && yogaNode) {
yogaNode.setGap(Yoga.Gutter.Column, value);
}

return node;
};
export const setColumnGap = setYogaValue('gap', Yoga.Gutter.Column);
2 changes: 1 addition & 1 deletion packages/layout/src/node/setYogaValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { SafeNode } from '../types';
* @returns Node instance wrapper
*/
const setYogaValue =
(attr: string, edge?: Yoga.Edge) =>
(attr: string, edge?: Yoga.Edge | Yoga.Gutter) =>
(value?: string | number | null) =>
(node: SafeNode) => {
const { yogaNode } = node;
Expand Down
87 changes: 87 additions & 0 deletions packages/layout/tests/node/setGap.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { beforeEach, describe, expect, test, vi } from 'vitest';

import * as Yoga from 'yoga-layout/load';

import { setRowGap, setColumnGap } from '../../src/node/setGap';
import { SafeNode } from '../../src/types';

describe('node setGap', () => {
const mock = vi.fn();
const mockPercent = vi.fn();

const node = {
type: 'VIEW',
props: {},
style: {},
children: [],
yogaNode: {
setGap: mock,
setGapPercent: mockPercent,
},
} as SafeNode;

const emptyNode = {
type: 'VIEW',
props: {},
style: {},
children: [],
box: { top: 0, right: 0, bottom: 0, left: 0, width: 10, height: 20 },
} as SafeNode;

beforeEach(() => {
mock.mockReset();
mockPercent.mockReset();
});

describe('setRowGap', () => {
test('should return node if no yoga node available', () => {
const result = setRowGap(null)(emptyNode);

expect(result).toBe(emptyNode);
});

test('should call appropiate yoga node method for numeric values', () => {
const result = setRowGap(50)(node);

expect(mock.mock.calls).toHaveLength(1);
expect(mock.mock.calls[0][0]).toBe(Yoga.Gutter.Row);
expect(mock.mock.calls[0][1]).toBe(50);
expect(result).toBe(node);
});

test('should call appropiate yoga node method for percent values', () => {
const result = setRowGap('50%')(node);

expect(mockPercent.mock.calls).toHaveLength(1);
expect(mockPercent.mock.calls[0][0]).toBe(Yoga.Gutter.Row);
expect(mockPercent.mock.calls[0][1]).toBe(50);
expect(result).toBe(node);
});
});

describe('setColumnGap', () => {
test('should return node if no yoga node available', () => {
const result = setColumnGap(null)(emptyNode);

expect(result).toBe(emptyNode);
});

test('should call appropiate yoga node method for numeric values', () => {
const result = setColumnGap(50)(node);

expect(mock.mock.calls).toHaveLength(1);
expect(mock.mock.calls[0][0]).toBe(Yoga.Gutter.Column);
expect(mock.mock.calls[0][1]).toBe(50);
expect(result).toBe(node);
});

test('should call appropiate yoga node method for percent values', () => {
const result = setColumnGap('50%')(node);

expect(mockPercent.mock.calls).toHaveLength(1);
expect(mockPercent.mock.calls[0][0]).toBe(Yoga.Gutter.Column);
expect(mockPercent.mock.calls[0][1]).toBe(50);
expect(result).toBe(node);
});
});
});