Skip to content

Commit 5bdfb6e

Browse files
committed
feat(Flex): add gap support
1 parent c2c8d50 commit 5bdfb6e

File tree

3 files changed

+351
-73
lines changed

3 files changed

+351
-73
lines changed

packages/react-core/src/layouts/Flex/Flex.tsx

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,141 @@ export interface FlexProps extends React.HTMLProps<HTMLDivElement> {
136136
| 'spaceItems3xl'
137137
| 'spaceItems4xl';
138138
};
139+
/** Whether to add a gap at various breakpoints. This will override spacers for the main axis. */
140+
gap?: {
141+
default?: 'gapNone' | 'gapXs' | 'gapSm' | 'gapMd' | 'gapLg' | 'gapXl' | 'gap2xl' | 'gap3xl' | 'gap4xl';
142+
sm?: 'gapNone' | 'gapXs' | 'gapSm' | 'gapMd' | 'gapLg' | 'gapXl' | 'gap2xl' | 'gap3xl' | 'gap4xl';
143+
md?: 'gapNone' | 'gapXs' | 'gapSm' | 'gapMd' | 'gapLg' | 'gapXl' | 'gap2xl' | 'gap3xl' | 'gap4xl';
144+
lg?: 'gapNone' | 'gapXs' | 'gapSm' | 'gapMd' | 'gapLg' | 'gapXl' | 'gap2xl' | 'gap3xl' | 'gap4xl';
145+
xl?: 'gapNone' | 'gapXs' | 'gapSm' | 'gapMd' | 'gapLg' | 'gapXl' | 'gap2xl' | 'gap3xl' | 'gap4xl';
146+
'2xl'?: 'gapNone' | 'gapXs' | 'gapSm' | 'gapMd' | 'gapLg' | 'gapXl' | 'gap2xl' | 'gap3xl' | 'gap4xl';
147+
};
148+
/** Whether to add a gap at various breakpoints. This will override spacers for the main axis. */
149+
rowGap?: {
150+
default?:
151+
| 'rowGapNone'
152+
| 'rowGapXs'
153+
| 'rowGapSm'
154+
| 'rowGapMd'
155+
| 'rowGapLg'
156+
| 'rowGapXl'
157+
| 'rowGap2xl'
158+
| 'rowGap3xl'
159+
| 'rowGap4xl';
160+
sm?:
161+
| 'rowGapNone'
162+
| 'rowGapXs'
163+
| 'rowGapSm'
164+
| 'rowGapMd'
165+
| 'rowGapLg'
166+
| 'rowGapXl'
167+
| 'rowGap2xl'
168+
| 'rowGap3xl'
169+
| 'rowGap4xl';
170+
md?:
171+
| 'rowGapNone'
172+
| 'rowGapXs'
173+
| 'rowGapSm'
174+
| 'rowGapMd'
175+
| 'rowGapLg'
176+
| 'rowGapXl'
177+
| 'rowGap2xl'
178+
| 'rowGap3xl'
179+
| 'rowGap4xl';
180+
lg?:
181+
| 'rowGapNone'
182+
| 'rowGapXs'
183+
| 'rowGapSm'
184+
| 'rowGapMd'
185+
| 'rowGapLg'
186+
| 'rowGapXl'
187+
| 'rowGap2xl'
188+
| 'rowGap3xl'
189+
| 'rowGap4xl';
190+
xl?:
191+
| 'rowGapNone'
192+
| 'rowGapXs'
193+
| 'rowGapSm'
194+
| 'rowGapMd'
195+
| 'rowGapLg'
196+
| 'rowGapXl'
197+
| 'rowGap2xl'
198+
| 'rowGap3xl'
199+
| 'rowGap4xl';
200+
'2xl'?:
201+
| 'rowGapNone'
202+
| 'rowGapXs'
203+
| 'rowGapSm'
204+
| 'rowGapMd'
205+
| 'rowGapLg'
206+
| 'rowGapXl'
207+
| 'rowGap2xl'
208+
| 'rowGap3xl'
209+
| 'rowGap4xl';
210+
};
211+
/** Whether to add a gap at various breakpoints. This will override spacers for the main axis. */
212+
columnGap?: {
213+
default?:
214+
| 'columnGapNone'
215+
| 'columnGapXs'
216+
| 'columnGapSm'
217+
| 'columnGapMd'
218+
| 'columnGapLg'
219+
| 'columnGapXl'
220+
| 'columnGap2xl'
221+
| 'columnGap3xl'
222+
| 'columnGap4xl';
223+
sm?:
224+
| 'columnGapNone'
225+
| 'columnGapXs'
226+
| 'columnGapSm'
227+
| 'columnGapMd'
228+
| 'columnGapLg'
229+
| 'columnGapXl'
230+
| 'columnGap2xl'
231+
| 'columnGap3xl'
232+
| 'columnGap4xl';
233+
md?:
234+
| 'columnGapNone'
235+
| 'columnGapXs'
236+
| 'columnGapSm'
237+
| 'columnGapMd'
238+
| 'columnGapLg'
239+
| 'columnGapXl'
240+
| 'columnGap2xl'
241+
| 'columnGap3xl'
242+
| 'columnGap4xl';
243+
lg?:
244+
| 'columnGapNone'
245+
| 'columnGapXs'
246+
| 'columnGapSm'
247+
| 'columnGapMd'
248+
| 'columnGapLg'
249+
| 'columnGapXl'
250+
| 'columnGap2xl'
251+
| 'columnGap3xl'
252+
| 'columnGap4xl';
253+
xl?:
254+
| 'columnGapNone'
255+
| 'columnGapXs'
256+
| 'columnGapSm'
257+
| 'columnGapMd'
258+
| 'columnGapLg'
259+
| 'columnGapXl'
260+
| 'columnGap2xl'
261+
| 'columnGap3xl'
262+
| 'columnGap4xl';
263+
'2xl'?:
264+
| 'columnGapNone'
265+
| 'columnGapXs'
266+
| 'columnGapSm'
267+
| 'columnGapMd'
268+
| 'columnGapLg'
269+
| 'columnGapXl'
270+
| 'columnGap2xl'
271+
| 'columnGap3xl'
272+
| 'columnGap4xl';
273+
};
139274
/** Whether to add flex: grow at various breakpoints */
140275
grow?: {
141276
default?: 'grow';
@@ -344,6 +479,9 @@ export const Flex: React.FunctionComponent<FlexProps> = ({
344479
component = 'div',
345480
spacer,
346481
spaceItems,
482+
gap,
483+
rowGap,
484+
columnGap,
347485
grow,
348486
shrink,
349487
flex,
@@ -380,6 +518,9 @@ export const Flex: React.FunctionComponent<FlexProps> = ({
380518
formatBreakpointMods(display, styles),
381519
formatBreakpointMods(fullWidth, styles),
382520
formatBreakpointMods(flexWrap, styles),
521+
formatBreakpointMods(gap, styles),
522+
formatBreakpointMods(rowGap, styles),
523+
formatBreakpointMods(columnGap, styles),
383524
className
384525
)}
385526
style={

packages/react-core/src/layouts/Flex/__tests__/Flex.test.tsx

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,36 +85,56 @@ describe('Flex', () => {
8585
],
8686
display: ['inlineFlex'],
8787
fullWidth: ['fullWidth'],
88-
flexWrap: ['wrap', 'wrapReverse', 'nowrap']
88+
flexWrap: ['wrap', 'wrapReverse', 'nowrap'],
89+
gap: ['gapNone', 'gapXs', 'gapSm', 'gapMd', 'gapLg', 'gapXl', 'gap2xl', 'gap3xl', 'gap4xl'],
90+
rowGap: [
91+
'rowGapNone',
92+
'rowGapXs',
93+
'rowGapSm',
94+
'rowGapMd',
95+
'rowGapLg',
96+
'rowGapXl',
97+
'rowGap2xl',
98+
'rowGap3xl',
99+
'rowGap4xl'
100+
],
101+
columnGap: [
102+
'columnGapNone',
103+
'columnGapXs',
104+
'columnGapSm',
105+
'columnGapMd',
106+
'columnGapLg',
107+
'columnGapXl',
108+
'columnGap2xl',
109+
'columnGap3xl',
110+
'columnGap4xl'
111+
]
89112
};
90113

91114
describe('flex modifiers', () => {
92115
Object.entries(flexModifiers)
93116
.map(([mod, values]) =>
94-
values.map(value => ({
117+
values.map((value) => ({
95118
[mod]: {
96119
default: value,
97120
sm: value,
121+
md: value,
98122
lg: value,
99123
xl: value,
100124
'2xl': value
101125
}
102126
}))
103127
)
104128
.reduce((acc, val) => acc.concat(val), [])
105-
.forEach(props =>
129+
.forEach((props) =>
106130
test(`${JSON.stringify(props)} add valid classes to Flex`, () => {
107131
render(
108132
<Flex {...props} data-testid="test-id">
109133
{JSON.stringify(props)}
110134
</Flex>
111135
);
112136

113-
const className = screen
114-
.getByTestId('test-id')
115-
.className.replace('pf-l-flex', '')
116-
.trim();
117-
137+
const className = screen.getByTestId('test-id').className.replace('pf-l-flex', '').trim();
118138
expect(className).not.toBe("''");
119139
expect(className).not.toBe('');
120140
})
@@ -134,7 +154,7 @@ describe('Flex', () => {
134154
describe('flexItem modifiers', () => {
135155
Object.entries(flexItemModifiers)
136156
.map(([mod, values]) =>
137-
values.map(value => ({
157+
values.map((value) => ({
138158
[mod]: {
139159
default: value,
140160
sm: value,
@@ -145,7 +165,7 @@ describe('Flex', () => {
145165
}))
146166
)
147167
.reduce((acc, val) => acc.concat(val), [])
148-
.forEach(props =>
168+
.forEach((props) =>
149169
test(`${JSON.stringify(props)} add valid classes to FlexItem`, () => {
150170
render(
151171
<FlexItem {...props} data-testid="test-id">

0 commit comments

Comments
 (0)