@sproutsocial/seeds-react-list 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +13 -0
- package/dist/esm/index.js +104 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -0
- package/jest.config.js +9 -0
- package/package.json +47 -0
- package/src/List.stories.tsx +362 -0
- package/src/List.tsx +23 -0
- package/src/ListItem.tsx +27 -0
- package/src/ListItemButton.tsx +32 -0
- package/src/ListItemButtonTypes.ts +3 -0
- package/src/ListItemContent.tsx +51 -0
- package/src/ListItemTypes.ts +26 -0
- package/src/ListTypes.ts +11 -0
- package/src/__tests__/List.test.tsx +74 -0
- package/src/index.ts +7 -0
- package/src/styles.tsx +14 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +12 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
yarn run v1.22.22
|
|
2
|
+
$ tsup --dts
|
|
3
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
4
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
5
|
+
[34mCLI[39m tsup v8.5.0
|
|
6
|
+
[34mCLI[39m Using tsup config: /home/runner/work/seeds/seeds/seeds-react/seeds-react-list/tsup.config.ts
|
|
7
|
+
[34mCLI[39m Target: es2022
|
|
8
|
+
[34mCLI[39m Cleaning output folder
|
|
9
|
+
[34mCJS[39m Build start
|
|
10
|
+
[34mESM[39m Build start
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m5.48 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m6.82 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 136ms
|
|
14
|
+
[32mESM[39m [1mdist/esm/index.js [22m[32m2.94 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/esm/index.js.map [22m[32m6.31 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 129ms
|
|
17
|
+
[34mDTS[39m Build start
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 14352ms
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m2.00 KB[39m
|
|
20
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m2.00 KB[39m
|
|
21
|
+
Done in 17.89s.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @sproutsocial/seeds-react-list
|
|
2
|
+
|
|
3
|
+
## 0.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9234e88: Correct list dependency versions
|
|
8
|
+
- ca88301: initial implementation of list
|
|
9
|
+
- Updated dependencies [fa7579a]
|
|
10
|
+
- @sproutsocial/seeds-react-theme@3.2.1
|
|
11
|
+
- @sproutsocial/seeds-react-box@1.1.7
|
|
12
|
+
- @sproutsocial/seeds-react-icon@2.0.1
|
|
13
|
+
- @sproutsocial/seeds-react-button@1.3.6
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// src/List.tsx
|
|
2
|
+
import "react";
|
|
3
|
+
import { Children } from "react";
|
|
4
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
5
|
+
|
|
6
|
+
// src/styles.tsx
|
|
7
|
+
import styled from "styled-components";
|
|
8
|
+
var Container = styled.ul`
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
list-style: none;
|
|
12
|
+
|
|
13
|
+
> li:first-child {
|
|
14
|
+
margin-top: 0;
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
var styles_default = Container;
|
|
18
|
+
|
|
19
|
+
// src/List.tsx
|
|
20
|
+
import { jsx } from "react/jsx-runtime";
|
|
21
|
+
var List = ({ as = "ul", children, ...rest }) => {
|
|
22
|
+
const listItems = Children.toArray(children);
|
|
23
|
+
return /* @__PURE__ */ jsx(styles_default, { as, ...rest, children: listItems.map((item, index) => /* @__PURE__ */ jsx(Box, { as: "li", mt: 300, children: item }, index)) });
|
|
24
|
+
};
|
|
25
|
+
List.displayName = "List";
|
|
26
|
+
var List_default = List;
|
|
27
|
+
|
|
28
|
+
// src/ListItem.tsx
|
|
29
|
+
import "react";
|
|
30
|
+
import Box2 from "@sproutsocial/seeds-react-box";
|
|
31
|
+
import "@sproutsocial/seeds-react-text";
|
|
32
|
+
import "@sproutsocial/seeds-react-icon";
|
|
33
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
34
|
+
var ListItem = ({ isBordered, children, ...rest }) => {
|
|
35
|
+
return /* @__PURE__ */ jsx2(
|
|
36
|
+
Box2,
|
|
37
|
+
{
|
|
38
|
+
borderRadius: "outer",
|
|
39
|
+
...isBordered ? {
|
|
40
|
+
border: 500,
|
|
41
|
+
borderColor: "container.border.base",
|
|
42
|
+
p: 300
|
|
43
|
+
} : {},
|
|
44
|
+
...rest,
|
|
45
|
+
children
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
ListItem.displayName = "ListItem";
|
|
50
|
+
var ListItem_default = ListItem;
|
|
51
|
+
|
|
52
|
+
// src/ListItemContent.tsx
|
|
53
|
+
import "react";
|
|
54
|
+
import Box3 from "@sproutsocial/seeds-react-box";
|
|
55
|
+
import Text2 from "@sproutsocial/seeds-react-text";
|
|
56
|
+
import { Icon as Icon2 } from "@sproutsocial/seeds-react-icon";
|
|
57
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
58
|
+
var ListItemContent = ({
|
|
59
|
+
text,
|
|
60
|
+
details,
|
|
61
|
+
aside,
|
|
62
|
+
iconName,
|
|
63
|
+
iconLabel,
|
|
64
|
+
actions,
|
|
65
|
+
...rest
|
|
66
|
+
}) => {
|
|
67
|
+
return /* @__PURE__ */ jsxs(
|
|
68
|
+
Box3,
|
|
69
|
+
{
|
|
70
|
+
display: "flex",
|
|
71
|
+
justifyContent: "space-between",
|
|
72
|
+
borderRadius: "outer",
|
|
73
|
+
alignItems: "baseline",
|
|
74
|
+
...rest,
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ jsxs(Box3, { display: "flex", flex: "1", children: [
|
|
77
|
+
iconName && /* @__PURE__ */ jsx3(Icon2, { mr: 300, name: iconName, size: "small", ariaLabel: iconLabel }),
|
|
78
|
+
/* @__PURE__ */ jsxs(Box3, { flex: "1", children: [
|
|
79
|
+
/* @__PURE__ */ jsx3(Text2.SmallSubHeadline, { as: "div", children: text }),
|
|
80
|
+
details && /* @__PURE__ */ jsx3(Text2.Byline, { as: "div", mt: 200, children: details })
|
|
81
|
+
] })
|
|
82
|
+
] }),
|
|
83
|
+
/* @__PURE__ */ jsxs(Box3, { display: "flex", alignItems: "center", gap: 300, flexShrink: 0, children: [
|
|
84
|
+
aside && /* @__PURE__ */ jsx3(Text2.Byline, { as: "div", children: aside }),
|
|
85
|
+
actions && /* @__PURE__ */ jsx3(Box3, { display: "flex", alignItems: "center", children: actions })
|
|
86
|
+
] })
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
ListItemContent.displayName = "ListItemContent";
|
|
92
|
+
var ListItemContent_default = ListItemContent;
|
|
93
|
+
|
|
94
|
+
// src/ListTypes.ts
|
|
95
|
+
import "react";
|
|
96
|
+
|
|
97
|
+
// src/ListItemTypes.ts
|
|
98
|
+
import "react";
|
|
99
|
+
export {
|
|
100
|
+
List_default as List,
|
|
101
|
+
ListItem_default as ListItem,
|
|
102
|
+
ListItemContent_default as ListItemContent
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/List.tsx","../../src/styles.tsx","../../src/ListItem.tsx","../../src/ListItemContent.tsx","../../src/ListTypes.ts","../../src/ListItemTypes.ts"],"sourcesContent":["import * as React from \"react\";\nimport { Children } from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Container from \"./styles\";\nimport type { TypeListProps } from \"./ListTypes\";\n\nconst List = ({ as = \"ul\", children, ...rest }: TypeListProps) => {\n const listItems = Children.toArray(children);\n\n return (\n <Container as={as} {...rest}>\n {listItems.map((item, index) => (\n <Box as=\"li\" key={index} mt={300}>\n {item}\n </Box>\n ))}\n </Container>\n );\n};\n\nList.displayName = \"List\";\n\nexport default List;\n","import styled from \"styled-components\";\nimport type { TypeListProps } from \"./ListTypes\";\n\nconst Container = styled.ul<TypeListProps>`\n margin: 0;\n padding: 0;\n list-style: none;\n\n > li:first-child {\n margin-top: 0;\n }\n`;\n\nexport default Container;\n","import * as React from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeListItemProps } from \"./ListItemTypes\";\n\nconst ListItem = ({ isBordered, children, ...rest }: TypeListItemProps) => {\n return (\n <Box\n borderRadius=\"outer\"\n {...(isBordered\n ? {\n border: 500,\n borderColor: \"container.border.base\",\n p: 300,\n }\n : {})}\n {...rest}\n >\n {children}\n </Box>\n );\n};\n\nListItem.displayName = \"ListItem\";\n\nexport default ListItem;\n","import * as React from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeListItemContentProps } from \"./ListItemTypes\";\n\nconst ListItemContent = ({\n text,\n details,\n aside,\n iconName,\n iconLabel,\n actions,\n ...rest\n}: TypeListItemContentProps) => {\n return (\n <Box\n display=\"flex\"\n justifyContent=\"space-between\"\n borderRadius=\"outer\"\n alignItems=\"baseline\"\n {...rest}\n >\n <Box display=\"flex\" flex=\"1\">\n {iconName && (\n <Icon mr={300} name={iconName} size=\"small\" ariaLabel={iconLabel} />\n )}\n <Box flex=\"1\">\n <Text.SmallSubHeadline as=\"div\">{text}</Text.SmallSubHeadline>\n {details && (\n <Text.Byline as=\"div\" mt={200}>\n {details}\n </Text.Byline>\n )}\n </Box>\n </Box>\n <Box display=\"flex\" alignItems=\"center\" gap={300} flexShrink={0}>\n {aside && <Text.Byline as=\"div\">{aside}</Text.Byline>}\n {actions && (\n <Box display=\"flex\" alignItems=\"center\">\n {actions}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nListItemContent.displayName = \"ListItemContent\";\n\nexport default ListItemContent;\n","import * as React from \"react\";\nimport type { TypeStyledComponentsCommonProps } from \"@sproutsocial/seeds-react-system-props\";\n\nexport type TypeListElement = \"ul\" | \"ol\";\n\nexport interface TypeListProps extends TypeStyledComponentsCommonProps {\n /** The HTML element to render as - either \"ul\" or \"ol\" */\n as?: TypeListElement;\n /** Array of elements to render as list items */\n children: React.ReactNode;\n}\n","import * as React from \"react\";\nimport type { TypeStyledComponentsCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeIconName } from \"@sproutsocial/seeds-react-icon\";\n\nexport interface TypeListItemProps extends TypeStyledComponentsCommonProps {\n /** If true, adds a border and padding around the list item which looks like a card or button */\n isBordered?: boolean;\n /** Children to display inside the list item */\n children: React.ReactNode;\n}\n\nexport interface TypeListItemContentProps\n extends TypeStyledComponentsCommonProps {\n /** Main text displayed as SmallSubheadline */\n text: React.ReactNode;\n /** Details text displayed as Byline below the main text */\n details?: React.ReactNode;\n /** Aside text displayed as Byline on the right side */\n aside?: React.ReactNode;\n /** Optional icon name to display on the left */\n iconName?: TypeIconName;\n /** Label used to describe the icon if not used with an accompanying visual label */\n iconLabel?: string;\n /** Actions to display on the right side (e.g., buttons, menus) */\n actions?: React.ReactNode;\n}\n"],"mappings":";AAAA,OAAuB;AACvB,SAAS,gBAAgB;AACzB,OAAO,SAAS;;;ACFhB,OAAO,YAAY;AAGnB,IAAM,YAAY,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUzB,IAAO,iBAAQ;;;ADDP;AANR,IAAM,OAAO,CAAC,EAAE,KAAK,MAAM,UAAU,GAAG,KAAK,MAAqB;AAChE,QAAM,YAAY,SAAS,QAAQ,QAAQ;AAE3C,SACE,oBAAC,kBAAU,IAAS,GAAG,MACpB,oBAAU,IAAI,CAAC,MAAM,UACpB,oBAAC,OAAI,IAAG,MAAiB,IAAI,KAC1B,kBADe,KAElB,CACD,GACH;AAEJ;AAEA,KAAK,cAAc;AAEnB,IAAO,eAAQ;;;AEtBf,OAAuB;AACvB,OAAOA,UAAS;AAChB,OAAiB;AACjB,OAAqB;AAKjB,gBAAAC,YAAA;AAFJ,IAAM,WAAW,CAAC,EAAE,YAAY,UAAU,GAAG,KAAK,MAAyB;AACzE,SACE,gBAAAA;AAAA,IAACD;AAAA,IAAA;AAAA,MACC,cAAa;AAAA,MACZ,GAAI,aACD;AAAA,QACE,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,GAAG;AAAA,MACL,IACA,CAAC;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,cAAc;AAEvB,IAAO,mBAAQ;;;AC1Bf,OAAuB;AACvB,OAAOE,UAAS;AAChB,OAAOC,WAAU;AACjB,SAAS,QAAAC,aAAY;AAsBX,gBAAAC,MAEF,YAFE;AAnBV,IAAM,kBAAkB,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAgC;AAC9B,SACE;AAAA,IAACH;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,gBAAe;AAAA,MACf,cAAa;AAAA,MACb,YAAW;AAAA,MACV,GAAG;AAAA,MAEJ;AAAA,6BAACA,MAAA,EAAI,SAAQ,QAAO,MAAK,KACtB;AAAA,sBACC,gBAAAG,KAACD,OAAA,EAAK,IAAI,KAAK,MAAM,UAAU,MAAK,SAAQ,WAAW,WAAW;AAAA,UAEpE,qBAACF,MAAA,EAAI,MAAK,KACR;AAAA,4BAAAG,KAACF,MAAK,kBAAL,EAAsB,IAAG,OAAO,gBAAK;AAAA,YACrC,WACC,gBAAAE,KAACF,MAAK,QAAL,EAAY,IAAG,OAAM,IAAI,KACvB,mBACH;AAAA,aAEJ;AAAA,WACF;AAAA,QACA,qBAACD,MAAA,EAAI,SAAQ,QAAO,YAAW,UAAS,KAAK,KAAK,YAAY,GAC3D;AAAA,mBAAS,gBAAAG,KAACF,MAAK,QAAL,EAAY,IAAG,OAAO,iBAAM;AAAA,UACtC,WACC,gBAAAE,KAACH,MAAA,EAAI,SAAQ,QAAO,YAAW,UAC5B,mBACH;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;;;AClDf,OAAuB;;;ACAvB,OAAuB;","names":["Box","jsx","Box","Text","Icon","jsx"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { TypeStyledComponentsCommonProps } from '@sproutsocial/seeds-react-system-props';
|
|
4
|
+
import { TypeIconName } from '@sproutsocial/seeds-react-icon';
|
|
5
|
+
|
|
6
|
+
type TypeListElement = "ul" | "ol";
|
|
7
|
+
interface TypeListProps extends TypeStyledComponentsCommonProps {
|
|
8
|
+
/** The HTML element to render as - either "ul" or "ol" */
|
|
9
|
+
as?: TypeListElement;
|
|
10
|
+
/** Array of elements to render as list items */
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare const List: {
|
|
15
|
+
({ as, children, ...rest }: TypeListProps): react_jsx_runtime.JSX.Element;
|
|
16
|
+
displayName: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface TypeListItemProps extends TypeStyledComponentsCommonProps {
|
|
20
|
+
/** If true, adds a border and padding around the list item which looks like a card or button */
|
|
21
|
+
isBordered?: boolean;
|
|
22
|
+
/** Children to display inside the list item */
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
}
|
|
25
|
+
interface TypeListItemContentProps extends TypeStyledComponentsCommonProps {
|
|
26
|
+
/** Main text displayed as SmallSubheadline */
|
|
27
|
+
text: React.ReactNode;
|
|
28
|
+
/** Details text displayed as Byline below the main text */
|
|
29
|
+
details?: React.ReactNode;
|
|
30
|
+
/** Aside text displayed as Byline on the right side */
|
|
31
|
+
aside?: React.ReactNode;
|
|
32
|
+
/** Optional icon name to display on the left */
|
|
33
|
+
iconName?: TypeIconName;
|
|
34
|
+
/** Label used to describe the icon if not used with an accompanying visual label */
|
|
35
|
+
iconLabel?: string;
|
|
36
|
+
/** Actions to display on the right side (e.g., buttons, menus) */
|
|
37
|
+
actions?: React.ReactNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const ListItem: {
|
|
41
|
+
({ isBordered, children, ...rest }: TypeListItemProps): react_jsx_runtime.JSX.Element;
|
|
42
|
+
displayName: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
declare const ListItemContent: {
|
|
46
|
+
({ text, details, aside, iconName, iconLabel, actions, ...rest }: TypeListItemContentProps): react_jsx_runtime.JSX.Element;
|
|
47
|
+
displayName: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { List, ListItem, ListItemContent, type TypeListElement, type TypeListItemContentProps, type TypeListItemProps, type TypeListProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { TypeStyledComponentsCommonProps } from '@sproutsocial/seeds-react-system-props';
|
|
4
|
+
import { TypeIconName } from '@sproutsocial/seeds-react-icon';
|
|
5
|
+
|
|
6
|
+
type TypeListElement = "ul" | "ol";
|
|
7
|
+
interface TypeListProps extends TypeStyledComponentsCommonProps {
|
|
8
|
+
/** The HTML element to render as - either "ul" or "ol" */
|
|
9
|
+
as?: TypeListElement;
|
|
10
|
+
/** Array of elements to render as list items */
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare const List: {
|
|
15
|
+
({ as, children, ...rest }: TypeListProps): react_jsx_runtime.JSX.Element;
|
|
16
|
+
displayName: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface TypeListItemProps extends TypeStyledComponentsCommonProps {
|
|
20
|
+
/** If true, adds a border and padding around the list item which looks like a card or button */
|
|
21
|
+
isBordered?: boolean;
|
|
22
|
+
/** Children to display inside the list item */
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
}
|
|
25
|
+
interface TypeListItemContentProps extends TypeStyledComponentsCommonProps {
|
|
26
|
+
/** Main text displayed as SmallSubheadline */
|
|
27
|
+
text: React.ReactNode;
|
|
28
|
+
/** Details text displayed as Byline below the main text */
|
|
29
|
+
details?: React.ReactNode;
|
|
30
|
+
/** Aside text displayed as Byline on the right side */
|
|
31
|
+
aside?: React.ReactNode;
|
|
32
|
+
/** Optional icon name to display on the left */
|
|
33
|
+
iconName?: TypeIconName;
|
|
34
|
+
/** Label used to describe the icon if not used with an accompanying visual label */
|
|
35
|
+
iconLabel?: string;
|
|
36
|
+
/** Actions to display on the right side (e.g., buttons, menus) */
|
|
37
|
+
actions?: React.ReactNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const ListItem: {
|
|
41
|
+
({ isBordered, children, ...rest }: TypeListItemProps): react_jsx_runtime.JSX.Element;
|
|
42
|
+
displayName: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
declare const ListItemContent: {
|
|
46
|
+
({ text, details, aside, iconName, iconLabel, actions, ...rest }: TypeListItemContentProps): react_jsx_runtime.JSX.Element;
|
|
47
|
+
displayName: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { List, ListItem, ListItemContent, type TypeListElement, type TypeListItemContentProps, type TypeListItemProps, type TypeListProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
List: () => List_default,
|
|
34
|
+
ListItem: () => ListItem_default,
|
|
35
|
+
ListItemContent: () => ListItemContent_default
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// src/List.tsx
|
|
40
|
+
var React = require("react");
|
|
41
|
+
var import_react = require("react");
|
|
42
|
+
var import_seeds_react_box = __toESM(require("@sproutsocial/seeds-react-box"));
|
|
43
|
+
|
|
44
|
+
// src/styles.tsx
|
|
45
|
+
var import_styled_components = __toESM(require("styled-components"));
|
|
46
|
+
var Container = import_styled_components.default.ul`
|
|
47
|
+
margin: 0;
|
|
48
|
+
padding: 0;
|
|
49
|
+
list-style: none;
|
|
50
|
+
|
|
51
|
+
> li:first-child {
|
|
52
|
+
margin-top: 0;
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
var styles_default = Container;
|
|
56
|
+
|
|
57
|
+
// src/List.tsx
|
|
58
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
59
|
+
var List = ({ as = "ul", children, ...rest }) => {
|
|
60
|
+
const listItems = import_react.Children.toArray(children);
|
|
61
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(styles_default, { as, ...rest, children: listItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_box.default, { as: "li", mt: 300, children: item }, index)) });
|
|
62
|
+
};
|
|
63
|
+
List.displayName = "List";
|
|
64
|
+
var List_default = List;
|
|
65
|
+
|
|
66
|
+
// src/ListItem.tsx
|
|
67
|
+
var React2 = require("react");
|
|
68
|
+
var import_seeds_react_box2 = __toESM(require("@sproutsocial/seeds-react-box"));
|
|
69
|
+
var import_seeds_react_text = require("@sproutsocial/seeds-react-text");
|
|
70
|
+
var import_seeds_react_icon = require("@sproutsocial/seeds-react-icon");
|
|
71
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
72
|
+
var ListItem = ({ isBordered, children, ...rest }) => {
|
|
73
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
74
|
+
import_seeds_react_box2.default,
|
|
75
|
+
{
|
|
76
|
+
borderRadius: "outer",
|
|
77
|
+
...isBordered ? {
|
|
78
|
+
border: 500,
|
|
79
|
+
borderColor: "container.border.base",
|
|
80
|
+
p: 300
|
|
81
|
+
} : {},
|
|
82
|
+
...rest,
|
|
83
|
+
children
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
ListItem.displayName = "ListItem";
|
|
88
|
+
var ListItem_default = ListItem;
|
|
89
|
+
|
|
90
|
+
// src/ListItemContent.tsx
|
|
91
|
+
var React3 = require("react");
|
|
92
|
+
var import_seeds_react_box3 = __toESM(require("@sproutsocial/seeds-react-box"));
|
|
93
|
+
var import_seeds_react_text2 = __toESM(require("@sproutsocial/seeds-react-text"));
|
|
94
|
+
var import_seeds_react_icon2 = require("@sproutsocial/seeds-react-icon");
|
|
95
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
96
|
+
var ListItemContent = ({
|
|
97
|
+
text,
|
|
98
|
+
details,
|
|
99
|
+
aside,
|
|
100
|
+
iconName,
|
|
101
|
+
iconLabel,
|
|
102
|
+
actions,
|
|
103
|
+
...rest
|
|
104
|
+
}) => {
|
|
105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
106
|
+
import_seeds_react_box3.default,
|
|
107
|
+
{
|
|
108
|
+
display: "flex",
|
|
109
|
+
justifyContent: "space-between",
|
|
110
|
+
borderRadius: "outer",
|
|
111
|
+
alignItems: "baseline",
|
|
112
|
+
...rest,
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_seeds_react_box3.default, { display: "flex", flex: "1", children: [
|
|
115
|
+
iconName && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_icon2.Icon, { mr: 300, name: iconName, size: "small", ariaLabel: iconLabel }),
|
|
116
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_seeds_react_box3.default, { flex: "1", children: [
|
|
117
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_text2.default.SmallSubHeadline, { as: "div", children: text }),
|
|
118
|
+
details && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_text2.default.Byline, { as: "div", mt: 200, children: details })
|
|
119
|
+
] })
|
|
120
|
+
] }),
|
|
121
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_seeds_react_box3.default, { display: "flex", alignItems: "center", gap: 300, flexShrink: 0, children: [
|
|
122
|
+
aside && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_text2.default.Byline, { as: "div", children: aside }),
|
|
123
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_box3.default, { display: "flex", alignItems: "center", children: actions })
|
|
124
|
+
] })
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
ListItemContent.displayName = "ListItemContent";
|
|
130
|
+
var ListItemContent_default = ListItemContent;
|
|
131
|
+
|
|
132
|
+
// src/ListTypes.ts
|
|
133
|
+
var React4 = require("react");
|
|
134
|
+
|
|
135
|
+
// src/ListItemTypes.ts
|
|
136
|
+
var React5 = require("react");
|
|
137
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
138
|
+
0 && (module.exports = {
|
|
139
|
+
List,
|
|
140
|
+
ListItem,
|
|
141
|
+
ListItemContent
|
|
142
|
+
});
|
|
143
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/List.tsx","../src/styles.tsx","../src/ListItem.tsx","../src/ListItemContent.tsx","../src/ListTypes.ts","../src/ListItemTypes.ts"],"sourcesContent":["import List from \"./List\";\nimport ListItem from \"./ListItem\";\nimport ListItemContent from \"./ListItemContent\";\n\nexport { List, ListItem, ListItemContent };\nexport * from \"./ListTypes\";\nexport * from \"./ListItemTypes\";\n","import * as React from \"react\";\nimport { Children } from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Container from \"./styles\";\nimport type { TypeListProps } from \"./ListTypes\";\n\nconst List = ({ as = \"ul\", children, ...rest }: TypeListProps) => {\n const listItems = Children.toArray(children);\n\n return (\n <Container as={as} {...rest}>\n {listItems.map((item, index) => (\n <Box as=\"li\" key={index} mt={300}>\n {item}\n </Box>\n ))}\n </Container>\n );\n};\n\nList.displayName = \"List\";\n\nexport default List;\n","import styled from \"styled-components\";\nimport type { TypeListProps } from \"./ListTypes\";\n\nconst Container = styled.ul<TypeListProps>`\n margin: 0;\n padding: 0;\n list-style: none;\n\n > li:first-child {\n margin-top: 0;\n }\n`;\n\nexport default Container;\n","import * as React from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeListItemProps } from \"./ListItemTypes\";\n\nconst ListItem = ({ isBordered, children, ...rest }: TypeListItemProps) => {\n return (\n <Box\n borderRadius=\"outer\"\n {...(isBordered\n ? {\n border: 500,\n borderColor: \"container.border.base\",\n p: 300,\n }\n : {})}\n {...rest}\n >\n {children}\n </Box>\n );\n};\n\nListItem.displayName = \"ListItem\";\n\nexport default ListItem;\n","import * as React from \"react\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport Text from \"@sproutsocial/seeds-react-text\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport type { TypeListItemContentProps } from \"./ListItemTypes\";\n\nconst ListItemContent = ({\n text,\n details,\n aside,\n iconName,\n iconLabel,\n actions,\n ...rest\n}: TypeListItemContentProps) => {\n return (\n <Box\n display=\"flex\"\n justifyContent=\"space-between\"\n borderRadius=\"outer\"\n alignItems=\"baseline\"\n {...rest}\n >\n <Box display=\"flex\" flex=\"1\">\n {iconName && (\n <Icon mr={300} name={iconName} size=\"small\" ariaLabel={iconLabel} />\n )}\n <Box flex=\"1\">\n <Text.SmallSubHeadline as=\"div\">{text}</Text.SmallSubHeadline>\n {details && (\n <Text.Byline as=\"div\" mt={200}>\n {details}\n </Text.Byline>\n )}\n </Box>\n </Box>\n <Box display=\"flex\" alignItems=\"center\" gap={300} flexShrink={0}>\n {aside && <Text.Byline as=\"div\">{aside}</Text.Byline>}\n {actions && (\n <Box display=\"flex\" alignItems=\"center\">\n {actions}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nListItemContent.displayName = \"ListItemContent\";\n\nexport default ListItemContent;\n","import * as React from \"react\";\nimport type { TypeStyledComponentsCommonProps } from \"@sproutsocial/seeds-react-system-props\";\n\nexport type TypeListElement = \"ul\" | \"ol\";\n\nexport interface TypeListProps extends TypeStyledComponentsCommonProps {\n /** The HTML element to render as - either \"ul\" or \"ol\" */\n as?: TypeListElement;\n /** Array of elements to render as list items */\n children: React.ReactNode;\n}\n","import * as React from \"react\";\nimport type { TypeStyledComponentsCommonProps } from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeIconName } from \"@sproutsocial/seeds-react-icon\";\n\nexport interface TypeListItemProps extends TypeStyledComponentsCommonProps {\n /** If true, adds a border and padding around the list item which looks like a card or button */\n isBordered?: boolean;\n /** Children to display inside the list item */\n children: React.ReactNode;\n}\n\nexport interface TypeListItemContentProps\n extends TypeStyledComponentsCommonProps {\n /** Main text displayed as SmallSubheadline */\n text: React.ReactNode;\n /** Details text displayed as Byline below the main text */\n details?: React.ReactNode;\n /** Aside text displayed as Byline on the right side */\n aside?: React.ReactNode;\n /** Optional icon name to display on the left */\n iconName?: TypeIconName;\n /** Label used to describe the icon if not used with an accompanying visual label */\n iconLabel?: string;\n /** Actions to display on the right side (e.g., buttons, menus) */\n actions?: React.ReactNode;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,YAAuB;AACvB,mBAAyB;AACzB,6BAAgB;;;ACFhB,+BAAmB;AAGnB,IAAM,YAAY,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUzB,IAAO,iBAAQ;;;ADDP;AANR,IAAM,OAAO,CAAC,EAAE,KAAK,MAAM,UAAU,GAAG,KAAK,MAAqB;AAChE,QAAM,YAAY,sBAAS,QAAQ,QAAQ;AAE3C,SACE,4CAAC,kBAAU,IAAS,GAAG,MACpB,oBAAU,IAAI,CAAC,MAAM,UACpB,4CAAC,uBAAAC,SAAA,EAAI,IAAG,MAAiB,IAAI,KAC1B,kBADe,KAElB,CACD,GACH;AAEJ;AAEA,KAAK,cAAc;AAEnB,IAAO,eAAQ;;;AEtBf,IAAAC,SAAuB;AACvB,IAAAC,0BAAgB;AAChB,8BAAiB;AACjB,8BAAqB;AAKjB,IAAAC,sBAAA;AAFJ,IAAM,WAAW,CAAC,EAAE,YAAY,UAAU,GAAG,KAAK,MAAyB;AACzE,SACE;AAAA,IAAC,wBAAAC;AAAA,IAAA;AAAA,MACC,cAAa;AAAA,MACZ,GAAI,aACD;AAAA,QACE,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,GAAG;AAAA,MACL,IACA,CAAC;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,cAAc;AAEvB,IAAO,mBAAQ;;;AC1Bf,IAAAC,SAAuB;AACvB,IAAAC,0BAAgB;AAChB,IAAAC,2BAAiB;AACjB,IAAAC,2BAAqB;AAsBX,IAAAC,sBAAA;AAnBV,IAAM,kBAAkB,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAgC;AAC9B,SACE;AAAA,IAAC,wBAAAC;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,gBAAe;AAAA,MACf,cAAa;AAAA,MACb,YAAW;AAAA,MACV,GAAG;AAAA,MAEJ;AAAA,sDAAC,wBAAAA,SAAA,EAAI,SAAQ,QAAO,MAAK,KACtB;AAAA,sBACC,6CAAC,iCAAK,IAAI,KAAK,MAAM,UAAU,MAAK,SAAQ,WAAW,WAAW;AAAA,UAEpE,8CAAC,wBAAAA,SAAA,EAAI,MAAK,KACR;AAAA,yDAAC,yBAAAC,QAAK,kBAAL,EAAsB,IAAG,OAAO,gBAAK;AAAA,YACrC,WACC,6CAAC,yBAAAA,QAAK,QAAL,EAAY,IAAG,OAAM,IAAI,KACvB,mBACH;AAAA,aAEJ;AAAA,WACF;AAAA,QACA,8CAAC,wBAAAD,SAAA,EAAI,SAAQ,QAAO,YAAW,UAAS,KAAK,KAAK,YAAY,GAC3D;AAAA,mBAAS,6CAAC,yBAAAC,QAAK,QAAL,EAAY,IAAG,OAAO,iBAAM;AAAA,UACtC,WACC,6CAAC,wBAAAD,SAAA,EAAI,SAAQ,QAAO,YAAW,UAC5B,mBACH;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;;;AClDf,IAAAE,SAAuB;;;ACAvB,IAAAC,SAAuB;","names":["styled","Box","React","import_seeds_react_box","import_jsx_runtime","Box","React","import_seeds_react_box","import_seeds_react_text","import_seeds_react_icon","import_jsx_runtime","Box","Text","React","React"]}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sproutsocial/seeds-react-list",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Seeds React List",
|
|
5
|
+
"author": "Sprout Social, Inc.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/esm/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup --dts",
|
|
12
|
+
"build:debug": "tsup --dts --metafile",
|
|
13
|
+
"dev": "tsup --watch --dts",
|
|
14
|
+
"clean": "rm -rf .turbo dist",
|
|
15
|
+
"clean:modules": "rm -rf node_modules",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"test:watch": "jest --watch --coverage=false"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@sproutsocial/seeds-react-theme": "^3.2.1",
|
|
22
|
+
"@sproutsocial/seeds-react-system-props": "^3.0.2",
|
|
23
|
+
"@sproutsocial/seeds-react-box": "^1.1.7",
|
|
24
|
+
"@sproutsocial/seeds-react-text": "^1.3.2",
|
|
25
|
+
"@sproutsocial/seeds-react-icon": "^2.0.1",
|
|
26
|
+
"@sproutsocial/seeds-react-button": "^1.3.6"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/react": "^18.0.0",
|
|
30
|
+
"@types/styled-components": "^5.1.26",
|
|
31
|
+
"@sproutsocial/eslint-config-seeds": "*",
|
|
32
|
+
"react": "^18.0.0",
|
|
33
|
+
"styled-components": "^5.2.3",
|
|
34
|
+
"tsup": "^8.3.4",
|
|
35
|
+
"typescript": "^5.6.2",
|
|
36
|
+
"@sproutsocial/seeds-tsconfig": "*",
|
|
37
|
+
"@sproutsocial/seeds-testing": "*",
|
|
38
|
+
"@sproutsocial/seeds-react-testing-library": "*",
|
|
39
|
+
"@sproutsocial/seeds-react-menu": "^1.6.17"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"styled-components": "^5.2.3"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import styled, { css } from "styled-components";
|
|
3
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
+
import List from "./List";
|
|
5
|
+
import ListItem from "./ListItem";
|
|
6
|
+
import ListItemButton from "./ListItemButton";
|
|
7
|
+
import { Button } from "@sproutsocial/seeds-react-button";
|
|
8
|
+
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
9
|
+
import {
|
|
10
|
+
ActionMenu,
|
|
11
|
+
MenuToggleButton,
|
|
12
|
+
MenuContent,
|
|
13
|
+
MenuItem,
|
|
14
|
+
} from "@sproutsocial/seeds-react-menu";
|
|
15
|
+
import { Message } from "@sproutsocial/seeds-react-message";
|
|
16
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
17
|
+
import ListItemContent from "./ListItemContent";
|
|
18
|
+
type CustomListArgs = React.ComponentProps<typeof List>;
|
|
19
|
+
|
|
20
|
+
const meta = {
|
|
21
|
+
title: "Components/List",
|
|
22
|
+
component: List,
|
|
23
|
+
decorators: [
|
|
24
|
+
(Story) => (
|
|
25
|
+
<Box maxWidth="500px">
|
|
26
|
+
<Story />
|
|
27
|
+
</Box>
|
|
28
|
+
),
|
|
29
|
+
],
|
|
30
|
+
} satisfies Meta<typeof List>;
|
|
31
|
+
|
|
32
|
+
export default meta;
|
|
33
|
+
type Story = StoryObj<CustomListArgs>;
|
|
34
|
+
|
|
35
|
+
export const UnorderedList: Story = {
|
|
36
|
+
name: "Unordered List",
|
|
37
|
+
render: () => {
|
|
38
|
+
return (
|
|
39
|
+
<List>
|
|
40
|
+
<ListItem>First item</ListItem>
|
|
41
|
+
<ListItem>Second item</ListItem>
|
|
42
|
+
<ListItem>Third item</ListItem>
|
|
43
|
+
</List>
|
|
44
|
+
);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const OrderedList: Story = {
|
|
49
|
+
name: "Ordered List",
|
|
50
|
+
render: () => {
|
|
51
|
+
return (
|
|
52
|
+
<List as="ol">
|
|
53
|
+
<ListItem>First item</ListItem>
|
|
54
|
+
<ListItem>Second item</ListItem>
|
|
55
|
+
<ListItem>Third item</ListItem>
|
|
56
|
+
</List>
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const WithListItems: Story = {
|
|
62
|
+
name: "With List Items",
|
|
63
|
+
render: () => {
|
|
64
|
+
return (
|
|
65
|
+
<List>
|
|
66
|
+
<ListItem>
|
|
67
|
+
<ListItemContent
|
|
68
|
+
text="Negative Spikes – Snouts Paws & Tails"
|
|
69
|
+
details="Are there any negative sentiment spikes in Snouts Paws & Tails Brand?"
|
|
70
|
+
aside="Nov 5"
|
|
71
|
+
/>
|
|
72
|
+
</ListItem>
|
|
73
|
+
<ListItem>
|
|
74
|
+
<ListItemContent
|
|
75
|
+
text="Another Item"
|
|
76
|
+
details="This is a detail about the item"
|
|
77
|
+
aside="Dec 10"
|
|
78
|
+
/>
|
|
79
|
+
</ListItem>
|
|
80
|
+
</List>
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const WithBorder: Story = {
|
|
86
|
+
name: "With Border",
|
|
87
|
+
render: () => {
|
|
88
|
+
return (
|
|
89
|
+
<List>
|
|
90
|
+
<ListItem isBordered>
|
|
91
|
+
<ListItemContent
|
|
92
|
+
text="Negative Spikes – Snouts Paws & Tails"
|
|
93
|
+
details="Are there any negative sentiment spikes in Snouts Paws & Tails Brand?"
|
|
94
|
+
aside="Nov 5"
|
|
95
|
+
/>
|
|
96
|
+
</ListItem>
|
|
97
|
+
<ListItem isBordered>
|
|
98
|
+
<ListItemContent
|
|
99
|
+
text="Another Item"
|
|
100
|
+
details="This is a detail about the item"
|
|
101
|
+
aside="Dec 10"
|
|
102
|
+
/>
|
|
103
|
+
</ListItem>
|
|
104
|
+
<ListItem isBordered>
|
|
105
|
+
<ListItemContent
|
|
106
|
+
text="Item without icon"
|
|
107
|
+
details="This item doesn't have an icon"
|
|
108
|
+
aside="Jan 1"
|
|
109
|
+
/>
|
|
110
|
+
</ListItem>
|
|
111
|
+
</List>
|
|
112
|
+
);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const WithIcons: Story = {
|
|
117
|
+
name: "With Icons",
|
|
118
|
+
render: () => {
|
|
119
|
+
return (
|
|
120
|
+
<List>
|
|
121
|
+
<ListItem>
|
|
122
|
+
<ListItemContent
|
|
123
|
+
iconName="tag-solid"
|
|
124
|
+
text="Negative Spikes – Snouts Paws & Tails"
|
|
125
|
+
details="Are there any negative sentiment spikes in Snouts Paws & Tails Brand?"
|
|
126
|
+
aside="Nov 5"
|
|
127
|
+
/>
|
|
128
|
+
</ListItem>
|
|
129
|
+
<ListItem>
|
|
130
|
+
<ListItemContent
|
|
131
|
+
text="Another Item"
|
|
132
|
+
details="This is a detail about the item"
|
|
133
|
+
aside="Dec 10"
|
|
134
|
+
iconName="tag-outline"
|
|
135
|
+
/>
|
|
136
|
+
</ListItem>
|
|
137
|
+
</List>
|
|
138
|
+
);
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// We will revisit this story when we have a more correct button component
|
|
143
|
+
/*
|
|
144
|
+
export const WithListItemButtons: Story = {
|
|
145
|
+
name: "With List Item Buttons",
|
|
146
|
+
render: () => {
|
|
147
|
+
return (
|
|
148
|
+
<List>
|
|
149
|
+
<ListItem>
|
|
150
|
+
<ListItemButton>
|
|
151
|
+
<ListItemContent
|
|
152
|
+
iconName="tag-solid"
|
|
153
|
+
text="Negative Spikes – Snouts Paws & Tails"
|
|
154
|
+
details="Are there any negative sentiment spikes in Snouts Paws & Tails Brand?"
|
|
155
|
+
aside="Nov 5"
|
|
156
|
+
/>
|
|
157
|
+
</ListItemButton>
|
|
158
|
+
</ListItem>
|
|
159
|
+
<ListItem>
|
|
160
|
+
<ListItemButton>
|
|
161
|
+
<ListItemContent
|
|
162
|
+
iconName="tag-outline"
|
|
163
|
+
text="Another Item"
|
|
164
|
+
details="This is a detail about the item"
|
|
165
|
+
aside="Dec 10"
|
|
166
|
+
/>
|
|
167
|
+
</ListItemButton>
|
|
168
|
+
</ListItem>
|
|
169
|
+
</List>
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
export const WithActions: Story = {
|
|
176
|
+
name: "With Actions",
|
|
177
|
+
render: () => {
|
|
178
|
+
return (
|
|
179
|
+
<List>
|
|
180
|
+
<ListItem>
|
|
181
|
+
<ListItemContent
|
|
182
|
+
iconName="tag-solid"
|
|
183
|
+
text="Groupon Babies is disconnected"
|
|
184
|
+
details="It looks like your Facebook profile needs reauthorization due to the..."
|
|
185
|
+
aside="2 days ago"
|
|
186
|
+
actions={
|
|
187
|
+
<Button appearance="unstyled" aria-label="Reconnect">
|
|
188
|
+
<Icon name="tag-outline" size="small" aria-hidden="true" />
|
|
189
|
+
</Button>
|
|
190
|
+
}
|
|
191
|
+
/>
|
|
192
|
+
</ListItem>
|
|
193
|
+
<ListItem>
|
|
194
|
+
<ListItemContent
|
|
195
|
+
iconName="tag-outline"
|
|
196
|
+
text="New secure forms submission received in a message."
|
|
197
|
+
aside="Nov 3, 2025"
|
|
198
|
+
actions={
|
|
199
|
+
<ActionMenu
|
|
200
|
+
menuToggleElement={
|
|
201
|
+
<MenuToggleButton
|
|
202
|
+
appearance="unstyled"
|
|
203
|
+
aria-label="More actions"
|
|
204
|
+
>
|
|
205
|
+
<Icon
|
|
206
|
+
name="ellipsis-horizontal-outline"
|
|
207
|
+
size="small"
|
|
208
|
+
aria-hidden="true"
|
|
209
|
+
/>
|
|
210
|
+
</MenuToggleButton>
|
|
211
|
+
}
|
|
212
|
+
>
|
|
213
|
+
<MenuContent>
|
|
214
|
+
<MenuItem
|
|
215
|
+
id="edit"
|
|
216
|
+
onClick={() => console.log("Edit clicked")}
|
|
217
|
+
>
|
|
218
|
+
Edit
|
|
219
|
+
</MenuItem>
|
|
220
|
+
<MenuItem
|
|
221
|
+
id="delete"
|
|
222
|
+
onClick={() => console.log("Delete clicked")}
|
|
223
|
+
>
|
|
224
|
+
Delete
|
|
225
|
+
</MenuItem>
|
|
226
|
+
</MenuContent>
|
|
227
|
+
</ActionMenu>
|
|
228
|
+
}
|
|
229
|
+
/>
|
|
230
|
+
</ListItem>
|
|
231
|
+
</List>
|
|
232
|
+
);
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const ErrorListItem = styled(ListItem)`
|
|
237
|
+
border: 1px solid ${(props: any) => props.theme.colors.container.border.base};
|
|
238
|
+
border-left: 4px solid
|
|
239
|
+
${(props: any) => props.theme.colors.container.border.error};
|
|
240
|
+
border-top-left-radius: 0;
|
|
241
|
+
border-bottom-left-radius: 0;
|
|
242
|
+
padding: ${(props: any) => props.theme.space[300]};
|
|
243
|
+
`;
|
|
244
|
+
const InfoListItem = styled(ListItem)`
|
|
245
|
+
border: 1px solid ${(props: any) => props.theme.colors.container.border.base};
|
|
246
|
+
border-left: 4px solid
|
|
247
|
+
${(props: any) => props.theme.colors.container.border.info};
|
|
248
|
+
border-top-left-radius: 0;
|
|
249
|
+
border-bottom-left-radius: 0;
|
|
250
|
+
padding: ${(props: any) => props.theme.space[300]};
|
|
251
|
+
`;
|
|
252
|
+
export const WithCustomStyles: Story = {
|
|
253
|
+
name: "With custom styles",
|
|
254
|
+
render: () => {
|
|
255
|
+
return (
|
|
256
|
+
<List>
|
|
257
|
+
<ErrorListItem>
|
|
258
|
+
<ListItemContent
|
|
259
|
+
iconName="tag-solid"
|
|
260
|
+
text="Groupon Babies is disconnected"
|
|
261
|
+
details="It looks like your Facebook profile needs reauthorization due to the..."
|
|
262
|
+
aside="2 days ago"
|
|
263
|
+
/>
|
|
264
|
+
</ErrorListItem>
|
|
265
|
+
<InfoListItem>
|
|
266
|
+
<ListItemContent
|
|
267
|
+
iconName="tag-outline"
|
|
268
|
+
text="New secure forms submission received in a message."
|
|
269
|
+
aside="Nov 3, 2025"
|
|
270
|
+
/>
|
|
271
|
+
</InfoListItem>
|
|
272
|
+
<ErrorListItem>
|
|
273
|
+
<ListItemContent
|
|
274
|
+
iconName="tag-solid"
|
|
275
|
+
text="Instagram's API periodically requires reauthorization"
|
|
276
|
+
details="Instagram's API periodically requires reauthorization. An Instagra..."
|
|
277
|
+
aside="Nov 3, 2025"
|
|
278
|
+
/>
|
|
279
|
+
</ErrorListItem>
|
|
280
|
+
</List>
|
|
281
|
+
);
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
export const WithMessages: Story = {
|
|
286
|
+
name: "With Messages",
|
|
287
|
+
render: () => {
|
|
288
|
+
return (
|
|
289
|
+
<List>
|
|
290
|
+
<ListItem>
|
|
291
|
+
<Message density="condensed">
|
|
292
|
+
<Message.Header>
|
|
293
|
+
<Box display="flex" alignItems="center">
|
|
294
|
+
<Message.Avatar mr={350} appearance="leaf" name="Chase McCoy" />
|
|
295
|
+
Attribution
|
|
296
|
+
</Box>
|
|
297
|
+
<Box>
|
|
298
|
+
<Message.Checkbox
|
|
299
|
+
id="message-checkbox-1"
|
|
300
|
+
ariaLabel="Message Checkbox"
|
|
301
|
+
onChange={() => {}}
|
|
302
|
+
/>
|
|
303
|
+
</Box>
|
|
304
|
+
</Message.Header>
|
|
305
|
+
<Message.Body>Message Content</Message.Body>
|
|
306
|
+
<Message.Footer>
|
|
307
|
+
<>
|
|
308
|
+
<Box ml={-350}>
|
|
309
|
+
<Message.Button>
|
|
310
|
+
<Icon name="comments-outline" mr={200} aria-hidden />
|
|
311
|
+
button with text
|
|
312
|
+
</Message.Button>
|
|
313
|
+
</Box>
|
|
314
|
+
<Box>
|
|
315
|
+
<Message.Button aria-label="Heart Icon Example">
|
|
316
|
+
<Icon name="heart-outline" aria-hidden />
|
|
317
|
+
</Message.Button>
|
|
318
|
+
<Message.Button aria-label="Tag Icon Example">
|
|
319
|
+
<Icon name="tag-outline" aria-hidden />
|
|
320
|
+
</Message.Button>
|
|
321
|
+
</Box>
|
|
322
|
+
</>
|
|
323
|
+
</Message.Footer>
|
|
324
|
+
</Message>
|
|
325
|
+
</ListItem>
|
|
326
|
+
<ListItem>
|
|
327
|
+
<Message density="condensed">
|
|
328
|
+
<Message.Header>
|
|
329
|
+
<Box display="flex" alignItems="center">
|
|
330
|
+
<Message.Avatar mr={350} appearance="leaf" name="Jane Doe" />
|
|
331
|
+
Another User
|
|
332
|
+
</Box>
|
|
333
|
+
<Box>
|
|
334
|
+
<Message.Checkbox
|
|
335
|
+
id="message-checkbox-2"
|
|
336
|
+
ariaLabel="Message Checkbox"
|
|
337
|
+
onChange={() => {}}
|
|
338
|
+
/>
|
|
339
|
+
</Box>
|
|
340
|
+
</Message.Header>
|
|
341
|
+
<Message.Body>Another message with different content</Message.Body>
|
|
342
|
+
<Message.Footer>
|
|
343
|
+
<>
|
|
344
|
+
<Box ml={-350}>
|
|
345
|
+
<Message.Button>
|
|
346
|
+
<Icon name="reply-outline" mr={200} aria-hidden />
|
|
347
|
+
Reply
|
|
348
|
+
</Message.Button>
|
|
349
|
+
</Box>
|
|
350
|
+
<Box>
|
|
351
|
+
<Message.Button aria-label="Heart Icon Example">
|
|
352
|
+
<Icon name="heart-outline" aria-hidden />
|
|
353
|
+
</Message.Button>
|
|
354
|
+
</Box>
|
|
355
|
+
</>
|
|
356
|
+
</Message.Footer>
|
|
357
|
+
</Message>
|
|
358
|
+
</ListItem>
|
|
359
|
+
</List>
|
|
360
|
+
);
|
|
361
|
+
},
|
|
362
|
+
};
|
package/src/List.tsx
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Children } from "react";
|
|
3
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
4
|
+
import Container from "./styles";
|
|
5
|
+
import type { TypeListProps } from "./ListTypes";
|
|
6
|
+
|
|
7
|
+
const List = ({ as = "ul", children, ...rest }: TypeListProps) => {
|
|
8
|
+
const listItems = Children.toArray(children);
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Container as={as} {...rest}>
|
|
12
|
+
{listItems.map((item, index) => (
|
|
13
|
+
<Box as="li" key={index} mt={300}>
|
|
14
|
+
{item}
|
|
15
|
+
</Box>
|
|
16
|
+
))}
|
|
17
|
+
</Container>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
List.displayName = "List";
|
|
22
|
+
|
|
23
|
+
export default List;
|
package/src/ListItem.tsx
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
3
|
+
import Text from "@sproutsocial/seeds-react-text";
|
|
4
|
+
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
5
|
+
import type { TypeListItemProps } from "./ListItemTypes";
|
|
6
|
+
|
|
7
|
+
const ListItem = ({ isBordered, children, ...rest }: TypeListItemProps) => {
|
|
8
|
+
return (
|
|
9
|
+
<Box
|
|
10
|
+
borderRadius="outer"
|
|
11
|
+
{...(isBordered
|
|
12
|
+
? {
|
|
13
|
+
border: 500,
|
|
14
|
+
borderColor: "container.border.base",
|
|
15
|
+
p: 300,
|
|
16
|
+
}
|
|
17
|
+
: {})}
|
|
18
|
+
{...rest}
|
|
19
|
+
>
|
|
20
|
+
{children}
|
|
21
|
+
</Box>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
ListItem.displayName = "ListItem";
|
|
26
|
+
|
|
27
|
+
export default ListItem;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
import Button from "@sproutsocial/seeds-react-button";
|
|
4
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
5
|
+
import Text from "@sproutsocial/seeds-react-text";
|
|
6
|
+
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
7
|
+
import type { TypeListItemButtonProps } from "./ListItemButtonTypes";
|
|
8
|
+
|
|
9
|
+
const StyledButton = styled(Button)`
|
|
10
|
+
border: 1px solid ${(props) => props.theme.colors.container.border.base};
|
|
11
|
+
text-align: initial;
|
|
12
|
+
font-weight: initial;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
// This button is not currently used. It is possible to pass interactive elements inside the button which is an accessibility violation.
|
|
16
|
+
// In order to reintroduce it, we will want to mimic confluence's approach of using relative positioning to add a sibling to content which allows clicking
|
|
17
|
+
const ListItemButton = ({
|
|
18
|
+
appearance = "unstyled",
|
|
19
|
+
width = "100%",
|
|
20
|
+
children,
|
|
21
|
+
...rest
|
|
22
|
+
}: TypeListItemButtonProps) => {
|
|
23
|
+
return (
|
|
24
|
+
<StyledButton appearance={appearance} width={width} {...rest}>
|
|
25
|
+
{children}
|
|
26
|
+
</StyledButton>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
ListItemButton.displayName = "ListItemButton";
|
|
31
|
+
|
|
32
|
+
export default ListItemButton;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Box from "@sproutsocial/seeds-react-box";
|
|
3
|
+
import Text from "@sproutsocial/seeds-react-text";
|
|
4
|
+
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
5
|
+
import type { TypeListItemContentProps } from "./ListItemTypes";
|
|
6
|
+
|
|
7
|
+
const ListItemContent = ({
|
|
8
|
+
text,
|
|
9
|
+
details,
|
|
10
|
+
aside,
|
|
11
|
+
iconName,
|
|
12
|
+
iconLabel,
|
|
13
|
+
actions,
|
|
14
|
+
...rest
|
|
15
|
+
}: TypeListItemContentProps) => {
|
|
16
|
+
return (
|
|
17
|
+
<Box
|
|
18
|
+
display="flex"
|
|
19
|
+
justifyContent="space-between"
|
|
20
|
+
borderRadius="outer"
|
|
21
|
+
alignItems="baseline"
|
|
22
|
+
{...rest}
|
|
23
|
+
>
|
|
24
|
+
<Box display="flex" flex="1">
|
|
25
|
+
{iconName && (
|
|
26
|
+
<Icon mr={300} name={iconName} size="small" ariaLabel={iconLabel} />
|
|
27
|
+
)}
|
|
28
|
+
<Box flex="1">
|
|
29
|
+
<Text.SmallSubHeadline as="div">{text}</Text.SmallSubHeadline>
|
|
30
|
+
{details && (
|
|
31
|
+
<Text.Byline as="div" mt={200}>
|
|
32
|
+
{details}
|
|
33
|
+
</Text.Byline>
|
|
34
|
+
)}
|
|
35
|
+
</Box>
|
|
36
|
+
</Box>
|
|
37
|
+
<Box display="flex" alignItems="center" gap={300} flexShrink={0}>
|
|
38
|
+
{aside && <Text.Byline as="div">{aside}</Text.Byline>}
|
|
39
|
+
{actions && (
|
|
40
|
+
<Box display="flex" alignItems="center">
|
|
41
|
+
{actions}
|
|
42
|
+
</Box>
|
|
43
|
+
)}
|
|
44
|
+
</Box>
|
|
45
|
+
</Box>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
ListItemContent.displayName = "ListItemContent";
|
|
50
|
+
|
|
51
|
+
export default ListItemContent;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { TypeStyledComponentsCommonProps } from "@sproutsocial/seeds-react-system-props";
|
|
3
|
+
import type { TypeIconName } from "@sproutsocial/seeds-react-icon";
|
|
4
|
+
|
|
5
|
+
export interface TypeListItemProps extends TypeStyledComponentsCommonProps {
|
|
6
|
+
/** If true, adds a border and padding around the list item which looks like a card or button */
|
|
7
|
+
isBordered?: boolean;
|
|
8
|
+
/** Children to display inside the list item */
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface TypeListItemContentProps
|
|
13
|
+
extends TypeStyledComponentsCommonProps {
|
|
14
|
+
/** Main text displayed as SmallSubheadline */
|
|
15
|
+
text: React.ReactNode;
|
|
16
|
+
/** Details text displayed as Byline below the main text */
|
|
17
|
+
details?: React.ReactNode;
|
|
18
|
+
/** Aside text displayed as Byline on the right side */
|
|
19
|
+
aside?: React.ReactNode;
|
|
20
|
+
/** Optional icon name to display on the left */
|
|
21
|
+
iconName?: TypeIconName;
|
|
22
|
+
/** Label used to describe the icon if not used with an accompanying visual label */
|
|
23
|
+
iconLabel?: string;
|
|
24
|
+
/** Actions to display on the right side (e.g., buttons, menus) */
|
|
25
|
+
actions?: React.ReactNode;
|
|
26
|
+
}
|
package/src/ListTypes.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { TypeStyledComponentsCommonProps } from "@sproutsocial/seeds-react-system-props";
|
|
3
|
+
|
|
4
|
+
export type TypeListElement = "ul" | "ol";
|
|
5
|
+
|
|
6
|
+
export interface TypeListProps extends TypeStyledComponentsCommonProps {
|
|
7
|
+
/** The HTML element to render as - either "ul" or "ol" */
|
|
8
|
+
as?: TypeListElement;
|
|
9
|
+
/** Array of elements to render as list items */
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@sproutsocial/seeds-react-testing-library";
|
|
3
|
+
import List from "../List";
|
|
4
|
+
|
|
5
|
+
describe("List", () => {
|
|
6
|
+
it("should render properly", async () => {
|
|
7
|
+
const { container, runA11yCheck } = render(
|
|
8
|
+
<List as="ul">
|
|
9
|
+
<div>Item 1</div>
|
|
10
|
+
<div>Item 2</div>
|
|
11
|
+
</List>
|
|
12
|
+
);
|
|
13
|
+
expect(container).toBeTruthy();
|
|
14
|
+
await runA11yCheck();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("should render as ul when as='ul'", () => {
|
|
18
|
+
const { container } = render(
|
|
19
|
+
<List as="ul">
|
|
20
|
+
<div>Item 1</div>
|
|
21
|
+
</List>
|
|
22
|
+
);
|
|
23
|
+
const listElement = container.querySelector("ul");
|
|
24
|
+
expect(listElement).toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should render as ol when as='ol'", () => {
|
|
28
|
+
const { container } = render(
|
|
29
|
+
<List as="ol">
|
|
30
|
+
<div>Item 1</div>
|
|
31
|
+
</List>
|
|
32
|
+
);
|
|
33
|
+
const listElement = container.querySelector("ol");
|
|
34
|
+
expect(listElement).toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("should wrap each child in an li element", () => {
|
|
38
|
+
const { container } = render(
|
|
39
|
+
<List as="ul">
|
|
40
|
+
<div>Item 1</div>
|
|
41
|
+
<div>Item 2</div>
|
|
42
|
+
<div>Item 3</div>
|
|
43
|
+
</List>
|
|
44
|
+
);
|
|
45
|
+
const listItems = container.querySelectorAll("li");
|
|
46
|
+
expect(listItems).toHaveLength(3);
|
|
47
|
+
expect(screen.getByText("Item 1")).toBeInTheDocument();
|
|
48
|
+
expect(screen.getByText("Item 2")).toBeInTheDocument();
|
|
49
|
+
expect(screen.getByText("Item 3")).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("should add mt={300} to all items except the first", () => {
|
|
53
|
+
const { container } = render(
|
|
54
|
+
<List as="ul">
|
|
55
|
+
<div>Item 1</div>
|
|
56
|
+
<div>Item 2</div>
|
|
57
|
+
<div>Item 3</div>
|
|
58
|
+
</List>
|
|
59
|
+
);
|
|
60
|
+
const listItems = container.querySelectorAll("li");
|
|
61
|
+
|
|
62
|
+
// Verify we have 3 items
|
|
63
|
+
expect(listItems).toHaveLength(3);
|
|
64
|
+
|
|
65
|
+
// First item should not have margin-top
|
|
66
|
+
const firstItem = listItems[0];
|
|
67
|
+
expect(firstItem).toBeInTheDocument();
|
|
68
|
+
|
|
69
|
+
// Other items should have mt={300} applied
|
|
70
|
+
// The mt prop will be converted to margin-top via styled-system
|
|
71
|
+
expect(listItems[1]).toBeInTheDocument();
|
|
72
|
+
expect(listItems[2]).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
});
|
package/src/index.ts
ADDED
package/src/styles.tsx
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import type { TypeListProps } from "./ListTypes";
|
|
3
|
+
|
|
4
|
+
const Container = styled.ul<TypeListProps>`
|
|
5
|
+
margin: 0;
|
|
6
|
+
padding: 0;
|
|
7
|
+
list-style: none;
|
|
8
|
+
|
|
9
|
+
> li:first-child {
|
|
10
|
+
margin-top: 0;
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export default Container;
|
package/tsconfig.json
ADDED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig((options) => ({
|
|
4
|
+
entry: ["src/index.ts"],
|
|
5
|
+
format: ["cjs", "esm"],
|
|
6
|
+
clean: true,
|
|
7
|
+
legacyOutput: true,
|
|
8
|
+
dts: options.dts,
|
|
9
|
+
external: ["react"],
|
|
10
|
+
sourcemap: true,
|
|
11
|
+
metafile: options.metafile,
|
|
12
|
+
}));
|