Skip to content

Commit 4c2a87e

Browse files
authored
new(List): Add reversed prop to visually reverse the list items. (#374)
1 parent 92bd3c3 commit 4c2a87e

File tree

7 files changed

+175
-30
lines changed

7 files changed

+175
-30
lines changed

packages/core/src/components/Breadcrumbs/Breadcrumb.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export default function Breadcrumb({
5353
};
5454

5555
return (
56-
<li className={cx(styles.li)}>
56+
<li>
5757
<ButtonOrLink
5858
{...aria}
5959
className={cx(

packages/core/src/components/Breadcrumbs/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type BreadcrumbsProps = {
1515
export default function Breadcrumbs({ accessibilityLabel, children }: BreadcrumbsProps) {
1616
return (
1717
<nav aria-label={accessibilityLabel}>
18-
<List horizontal ordered>
18+
<List horizontal gutter ordered>
1919
{children}
2020
</List>
2121
</nav>

packages/core/src/components/Breadcrumbs/styles.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,4 @@ export const styleSheetBreadcrumb: StyleSheet = ({ color, font, pattern, transit
4848
breadcrumb_selected: {
4949
fontWeight: font.weights.bold,
5050
},
51-
52-
li: {
53-
marginRight: unit,
54-
55-
':last-child': {
56-
marginRight: 0,
57-
},
58-
},
5951
});

packages/core/src/components/List/index.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import useStyles, { StyleSheet } from '../../hooks/useStyles';
3-
import Item, { ListItemProps } from './Item';
3+
import Item from './Item';
44
import { styleSheetList } from './styles';
55

66
export { Item };
@@ -16,6 +16,8 @@ export type ListProps = {
1616
middleAlign?: boolean;
1717
/** Renders an `<ol></ol>`. */
1818
ordered?: boolean;
19+
/** Render items in reverse order visually. */
20+
reversed?: boolean;
1921
/** Wrap horizontal list. */
2022
wrap?: boolean;
2123
/** Custom style sheet. */
@@ -28,6 +30,7 @@ export default function List({
2830
horizontal,
2931
middleAlign,
3032
ordered,
33+
reversed,
3134
wrap,
3235
styleSheet,
3336
}: ListProps) {
@@ -38,20 +41,28 @@ export default function List({
3841
<Tag
3942
className={cx(
4043
styles.list,
44+
reversed && styles.list_reversed,
4145
!horizontal && gutter && styles.list_gutter,
46+
!horizontal && gutter && reversed && styles.list_gutter_reversed,
4247
horizontal && styles.list_horizontal,
48+
horizontal && reversed && styles.list_reversed_horizontal,
4349
horizontal && gutter && styles.list_gutter_horizontal,
44-
horizontal && wrap && styles.list_horizontal_wrap,
50+
horizontal && gutter && reversed && styles.list_gutter_horizontal_reversed,
51+
horizontal && wrap && styles.list_wrap,
4552
middleAlign && styles.list_middleAlign,
4653
)}
4754
>
48-
{React.Children.map(children, (child) => {
55+
{React.Children.map(children as React.ReactElement[], (child: React.ReactElement) => {
4956
if (!child) {
5057
return null;
5158
}
5259

53-
if (horizontal) {
54-
return React.cloneElement(child as React.ReactElement<ListItemProps>, { horizontal });
60+
if (horizontal && (child.props.compact || child.props.spacious || child.props.spacious)) {
61+
if (child.type === Item) {
62+
return React.cloneElement(child, { horizontal });
63+
}
64+
65+
return <Item horizontal>{child.props.children}</Item>;
5566
}
5667

5768
return child;

packages/core/src/components/List/story.tsx

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ export function listWithHorizontal() {
7575
</Text>
7676
</Item>
7777

78-
<Item>
78+
<li>
7979
<Text>
8080
<LoremIpsum short />
8181
</Text>
82-
</Item>
82+
</li>
8383

8484
<Item>
8585
<Text>
@@ -103,11 +103,11 @@ export function listWithHorizontalAndGutter() {
103103
</Text>
104104
</Item>
105105

106-
<Item>
106+
<li>
107107
<Text>
108108
<LoremIpsum short />
109109
</Text>
110-
</Item>
110+
</li>
111111

112112
<Item>
113113
<Text>
@@ -131,13 +131,13 @@ export function listWithHorizontalMiddleAlignAndGutter() {
131131
</Text>
132132
</Item>
133133

134-
<Item>
134+
<li>
135135
<Text>
136136
<LoremIpsum short />
137137
<br />
138138
<LoremIpsum short />
139139
</Text>
140-
</Item>
140+
</li>
141141

142142
<Item>
143143
<Text>
@@ -180,7 +180,47 @@ listWithHorizontalAndWrap.story = {
180180
name: 'List with `horizontal` and `wrap`.',
181181
};
182182

183-
export function listWithOrderedToRenderAsOlOl() {
183+
export function listWithReversed() {
184+
return (
185+
<>
186+
<List reversed>
187+
<Item>
188+
<Text>1</Text>
189+
</Item>
190+
191+
<li>
192+
<Text>2</Text>
193+
</li>
194+
195+
<Item>
196+
<Text>3</Text>
197+
</Item>
198+
</List>
199+
200+
<br />
201+
202+
<List horizontal reversed>
203+
<Item>
204+
<Text>1</Text>
205+
</Item>
206+
207+
<li>
208+
<Text>2</Text>
209+
</li>
210+
211+
<Item>
212+
<Text>3</Text>
213+
</Item>
214+
</List>
215+
</>
216+
);
217+
}
218+
219+
listWithReversed.story = {
220+
name: 'List with `reversed` and List with `horizontal reversed`.',
221+
};
222+
223+
export function listWithOrderedToRenderAsOl() {
184224
return (
185225
<List ordered>
186226
<Item>
@@ -204,7 +244,7 @@ export function listWithOrderedToRenderAsOlOl() {
204244
);
205245
}
206246

207-
listWithOrderedToRenderAsOlOl.story = {
247+
listWithOrderedToRenderAsOl.story = {
208248
name: 'List with `ordered` to render as `<ol></ol>`.',
209249
};
210250

@@ -291,3 +331,31 @@ export function itemsWithSpaciousPadding() {
291331
itemsWithSpaciousPadding.story = {
292332
name: 'Items with `spacious` padding.',
293333
};
334+
335+
export function itemsWithBorderedHorizontal() {
336+
return (
337+
<List horizontal gutter>
338+
<Item compact bordered>
339+
<Text>
340+
<LoremIpsum short />
341+
</Text>
342+
</Item>
343+
344+
<Item compact bordered>
345+
<Text>
346+
<LoremIpsum short />
347+
</Text>
348+
</Item>
349+
350+
<Item compact bordered>
351+
<Text>
352+
<LoremIpsum short />
353+
</Text>
354+
</Item>
355+
</List>
356+
);
357+
}
358+
359+
itemsWithBorderedHorizontal.story = {
360+
name: 'Items with `bordered`, `compact`, `horizontal`, and `gutter`.',
361+
};

packages/core/src/components/List/styles.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ import { StyleSheet } from '../../hooks/useStyles';
22

33
export const styleSheetList: StyleSheet = ({ unit }) => ({
44
list: {
5+
display: 'flex',
6+
flexDirection: 'column',
57
listStyle: 'none',
68
margin: 0,
79
padding: 0,
810
},
911

12+
list_horizontal: {
13+
flexDirection: 'row',
14+
},
15+
1016
list_gutter: {
1117
'@selectors': {
1218
'> li': {
13-
marginBottom: unit,
19+
margin: `0 0 ${unit}px 0`,
1420
},
1521

1622
'> li:last-child': {
@@ -19,11 +25,22 @@ export const styleSheetList: StyleSheet = ({ unit }) => ({
1925
},
2026
},
2127

28+
list_gutter_reversed: {
29+
'@selectors': {
30+
'> li': {
31+
margin: `${unit}px 0 0 0`,
32+
},
33+
34+
'> li:last-child': {
35+
marginTop: 0,
36+
},
37+
},
38+
},
39+
2240
list_gutter_horizontal: {
2341
'@selectors': {
2442
'> li': {
25-
marginBottom: 0,
26-
marginRight: unit * 2,
43+
margin: `0 ${unit * 2}px 0 0`,
2744
},
2845

2946
'> li:last-child': {
@@ -32,15 +49,32 @@ export const styleSheetList: StyleSheet = ({ unit }) => ({
3249
},
3350
},
3451

35-
list_horizontal: {
36-
display: 'flex',
52+
list_gutter_horizontal_reversed: {
53+
'@selectors': {
54+
'> li': {
55+
margin: `0 0 0 ${unit * 2}px`,
56+
},
57+
58+
'> li:last-child': {
59+
marginLeft: 0,
60+
},
61+
},
3762
},
3863

3964
list_middleAlign: {
4065
alignItems: 'center',
4166
},
4267

43-
list_horizontal_wrap: {
68+
list_reversed: {
69+
flexDirection: 'column-reverse',
70+
},
71+
72+
list_reversed_horizontal: {
73+
flexDirection: 'row-reverse',
74+
justifyContent: 'flex-end',
75+
},
76+
77+
list_wrap: {
4478
flexWrap: 'wrap',
4579
},
4680
});

packages/core/test/components/List.test.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,36 @@ describe('<List />', () => {
7171
expect(wrapper.prop('className')).toContain('list_gutter');
7272
});
7373

74+
it('renders a reversed list with gutters', () => {
75+
const wrapper = shallow(
76+
<List gutter reversed>
77+
<Item>Item 1</Item>
78+
</List>,
79+
);
80+
81+
expect(wrapper.prop('className')).toContain('list_gutter_reversed');
82+
});
83+
7484
it('renders a horizontal list with gutters', () => {
7585
const wrapper = shallow(
76-
<List gutter horizontal>
86+
<List horizontal gutter>
7787
<Item>Item 1</Item>
7888
</List>,
7989
);
8090

8191
expect(wrapper.prop('className')).toContain('list_gutter_horizontal');
8292
});
8393

94+
it('renders a reversed horizontal list with gutters', () => {
95+
const wrapper = shallow(
96+
<List reversed horizontal gutter>
97+
<Item>Item 1</Item>
98+
</List>,
99+
);
100+
101+
expect(wrapper.prop('className')).toContain('list_gutter_horizontal_reversed');
102+
});
103+
84104
it('renders a horizontal list', () => {
85105
const wrapper = shallow(
86106
<List horizontal>
@@ -91,6 +111,26 @@ describe('<List />', () => {
91111
expect(wrapper.prop('className')).toContain('list_horizontal');
92112
});
93113

114+
it('renders a reversed list', () => {
115+
const wrapper = shallow(
116+
<List reversed>
117+
<Item>Item 1</Item>
118+
</List>,
119+
);
120+
121+
expect(wrapper.prop('className')).toContain('list_reversed');
122+
});
123+
124+
it('renders a horizontal reversed list', () => {
125+
const wrapper = shallow(
126+
<List horizontal reversed>
127+
<Item>Item 1</Item>
128+
</List>,
129+
);
130+
131+
expect(wrapper.prop('className')).toContain('list_reversed_horizontal');
132+
});
133+
94134
it('renders a list with middleAlign', () => {
95135
const wrapper = shallow(
96136
<List middleAlign>

0 commit comments

Comments
 (0)