@sproutsocial/seeds-react-profile 0.1.3
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/.eslintignore +6 -0
- package/.eslintrc.js +4 -0
- package/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +32 -0
- package/dist/esm/index.js +57 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +61 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/jest.config.js +9 -0
- package/package.json +49 -0
- package/src/InlineProfile.stories.tsx +95 -0
- package/src/InlineProfile.tsx +75 -0
- package/src/ProfileToken.stories.tsx +202 -0
- package/src/ProfileToken.tsx +20 -0
- package/src/__tests__/InlineProfile.test.tsx +83 -0
- package/src/__tests__/ProfileToken.test.tsx +54 -0
- package/src/index.ts +3 -0
- package/src/types.ts +26 -0
- package/tsconfig.json +15 -0
- package/tsup.config.ts +12 -0
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
|
@@ -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-profile/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[32m3.82 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m3.91 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 90ms
|
|
14
|
+
[32mESM[39m [1mdist/esm/index.js [22m[32m1.69 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/esm/index.js.map [22m[32m3.73 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 80ms
|
|
17
|
+
[34mDTS[39m Build start
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 5534ms
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m2.17 KB[39m
|
|
20
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m2.17 KB[39m
|
|
21
|
+
Done in 7.52s.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# @sproutsocial/seeds-react-profile
|
|
2
|
+
|
|
3
|
+
## 0.1.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [2b1bb50]
|
|
8
|
+
- @sproutsocial/seeds-react-card@1.1.13
|
|
9
|
+
|
|
10
|
+
## 0.1.2
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [119f4b5]
|
|
15
|
+
- @sproutsocial/seeds-react-avatar@1.0.8
|
|
16
|
+
|
|
17
|
+
## 0.1.1
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [d021ffc]
|
|
22
|
+
- @sproutsocial/seeds-react-partner-logo@1.5.0
|
|
23
|
+
- @sproutsocial/seeds-react-card@1.1.12
|
|
24
|
+
- @sproutsocial/seeds-react-token@1.4.9
|
|
25
|
+
- @sproutsocial/seeds-react-avatar@1.0.7
|
|
26
|
+
- @sproutsocial/seeds-react-icon@2.0.4
|
|
27
|
+
|
|
28
|
+
## 0.1.0
|
|
29
|
+
|
|
30
|
+
### Minor Changes
|
|
31
|
+
|
|
32
|
+
- ecf1622: Add new seeds-react-profile package with InlineProfile and ProfileToken components.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/InlineProfile.tsx
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
import { Text } from "@sproutsocial/seeds-react-text";
|
|
4
|
+
import { PartnerLogo } from "@sproutsocial/seeds-react-partner-logo";
|
|
5
|
+
import { Avatar } from "@sproutsocial/seeds-react-avatar";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
var InlineProfileContainer = styled.div`
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: row;
|
|
10
|
+
align-items: center;
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
`;
|
|
13
|
+
var InlineProfileBody = styled.span`
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
margin-left: 8px;
|
|
17
|
+
`;
|
|
18
|
+
var InlineProfile = ({
|
|
19
|
+
name,
|
|
20
|
+
secondaryName,
|
|
21
|
+
partnerName,
|
|
22
|
+
partnerLogoLabel,
|
|
23
|
+
avatarSize = "22px",
|
|
24
|
+
img,
|
|
25
|
+
children
|
|
26
|
+
}) => {
|
|
27
|
+
return /* @__PURE__ */ jsxs(InlineProfileContainer, { children: [
|
|
28
|
+
/* @__PURE__ */ jsx(Avatar, { size: avatarSize, src: img, name }),
|
|
29
|
+
partnerName && /* @__PURE__ */ jsx(
|
|
30
|
+
PartnerLogo,
|
|
31
|
+
{
|
|
32
|
+
size: "small",
|
|
33
|
+
partnerName,
|
|
34
|
+
ml: 300,
|
|
35
|
+
"aria-label": partnerLogoLabel
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
/* @__PURE__ */ jsx(Text, { fontSize: 200, fontWeight: "semibold", ml: 300, truncated: true, children: name }),
|
|
39
|
+
secondaryName && /* @__PURE__ */ jsx(Text, { fontSize: 200, ml: 300, fontWeight: "normal", truncated: true, children: secondaryName }),
|
|
40
|
+
/* @__PURE__ */ jsx(InlineProfileBody, { children })
|
|
41
|
+
] });
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/ProfileToken.tsx
|
|
45
|
+
import "react";
|
|
46
|
+
import { Token } from "@sproutsocial/seeds-react-token";
|
|
47
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
48
|
+
var ProfileToken = ({
|
|
49
|
+
tokenProps,
|
|
50
|
+
className,
|
|
51
|
+
...props
|
|
52
|
+
}) => /* @__PURE__ */ jsx2(Token, { className, closeable: false, ...tokenProps, children: /* @__PURE__ */ jsx2(InlineProfile, { ...props }) });
|
|
53
|
+
export {
|
|
54
|
+
InlineProfile,
|
|
55
|
+
ProfileToken
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/InlineProfile.tsx","../../src/ProfileToken.tsx"],"sourcesContent":["import styled from \"styled-components\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { PartnerLogo } from \"@sproutsocial/seeds-react-partner-logo\";\nimport { Avatar } from \"@sproutsocial/seeds-react-avatar\";\nimport type { TypeInlineProfileProps } from \"./types\";\n\nconst InlineProfileContainer = styled.div`\n display: flex;\n flex-direction: row;\n align-items: center;\n max-width: 100%;\n`;\n\nconst InlineProfileBody = styled.span`\n display: flex;\n align-items: center;\n margin-left: 8px;\n`;\n\n/**\n *\n * @param props - Profile props\n * @param props.name - Name of the profile\n * @param props.secondaryName - Secondary name of the profile\n * @param props.partnerName - Partner logo name\n * @param props.partnerLogoLabel - Aria-label for the partner logo\n * @param props.avatarSize - Size of the avatar\n * @param props.img - Image URL for the avatar\n * @param props.children - Additional elements to render within the profile component\n * @returns JSX.Element representing a user profile\n *\n * @example\n * <InlineProfile\n * name=\"John Doe\"\n * secondaryName=\"johndoe123\"\n * partnerName=\"facebook\"\n * partnerLogoLabel=\"Facebook Logo\"\n * avatarSize=\"24px\"\n * img=\"https://example.com/avatar.jpg\"\n * >\n * <Badge text=\"Moderator\" badgeColor=\"green\" />\n * </InlineProfile>\n */\nexport const InlineProfile = ({\n name,\n secondaryName,\n partnerName,\n partnerLogoLabel,\n avatarSize = \"22px\",\n img,\n children,\n}: TypeInlineProfileProps) => {\n return (\n <InlineProfileContainer>\n <Avatar size={avatarSize} src={img} name={name} />\n {partnerName && (\n <PartnerLogo\n size=\"small\"\n partnerName={partnerName}\n ml={300}\n aria-label={partnerLogoLabel}\n />\n )}\n <Text fontSize={200} fontWeight=\"semibold\" ml={300} truncated={true}>\n {name}\n </Text>\n {secondaryName && (\n <Text fontSize={200} ml={300} fontWeight=\"normal\" truncated={true}>\n {secondaryName}\n </Text>\n )}\n <InlineProfileBody>{children}</InlineProfileBody>\n </InlineProfileContainer>\n );\n};\n","import React from \"react\";\nimport { Token } from \"@sproutsocial/seeds-react-token\";\nimport { InlineProfile } from \"./InlineProfile\";\nimport type { ProfileTokenProps } from \"./types\";\n\n/**\n * A ProfileToken component that wraps CompactProfile in a Seeds Token component.\n * This token is not closable and provides a compact way to display profile information inline.\n */\nexport const ProfileToken: React.FC<ProfileTokenProps> = ({\n tokenProps,\n className,\n ...props\n}) => (\n <Token className={className} closeable={false} {...tokenProps}>\n <InlineProfile {...props} />\n </Token>\n);\n\nexport default ProfileToken;\n"],"mappings":";AAAA,OAAO,YAAY;AACnB,SAAS,YAAY;AACrB,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AAkDnB,SACE,KADF;AA/CJ,IAAM,yBAAyB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,IAAM,oBAAoB,OAAO;AAAA;AAAA;AAAA;AAAA;AA8B1B,IAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AACF,MAA8B;AAC5B,SACE,qBAAC,0BACC;AAAA,wBAAC,UAAO,MAAM,YAAY,KAAK,KAAK,MAAY;AAAA,IAC/C,eACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,IAAI;AAAA,QACJ,cAAY;AAAA;AAAA,IACd;AAAA,IAEF,oBAAC,QAAK,UAAU,KAAK,YAAW,YAAW,IAAI,KAAK,WAAW,MAC5D,gBACH;AAAA,IACC,iBACC,oBAAC,QAAK,UAAU,KAAK,IAAI,KAAK,YAAW,UAAS,WAAW,MAC1D,yBACH;AAAA,IAEF,oBAAC,qBAAmB,UAAS;AAAA,KAC/B;AAEJ;;;AC1EA,OAAkB;AAClB,SAAS,aAAa;AAclB,gBAAAA,YAAA;AANG,IAAM,eAA4C,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,gBAAAA,KAAC,SAAM,WAAsB,WAAW,OAAQ,GAAG,YACjD,0BAAAA,KAAC,iBAAe,GAAG,OAAO,GAC5B;","names":["jsx"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { EnumLogoNamesWithoutVariants } from '@sproutsocial/seeds-partner-logos';
|
|
3
|
+
import Token from '@sproutsocial/seeds-react-token';
|
|
4
|
+
import React$1 from 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Profile Component Types
|
|
8
|
+
*
|
|
9
|
+
* This file contains TypeScript interfaces and types for the Profile component
|
|
10
|
+
* that can be used by backend services to render user profile data.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
interface TypeInlineProfileProps {
|
|
14
|
+
name: string;
|
|
15
|
+
secondaryName?: string;
|
|
16
|
+
avatarSize?: string;
|
|
17
|
+
partnerName?: EnumLogoNamesWithoutVariants;
|
|
18
|
+
partnerLogoLabel?: string;
|
|
19
|
+
img?: string;
|
|
20
|
+
children?: React.ReactNode | React.ReactNode[];
|
|
21
|
+
}
|
|
22
|
+
interface ProfileTokenProps extends TypeInlineProfileProps {
|
|
23
|
+
/** Additional CSS class name */
|
|
24
|
+
className?: string;
|
|
25
|
+
/** Additional props to pass to the Token component */
|
|
26
|
+
tokenProps?: Omit<React.ComponentProps<typeof Token>, "children">;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param props - Profile props
|
|
32
|
+
* @param props.name - Name of the profile
|
|
33
|
+
* @param props.secondaryName - Secondary name of the profile
|
|
34
|
+
* @param props.partnerName - Partner logo name
|
|
35
|
+
* @param props.partnerLogoLabel - Aria-label for the partner logo
|
|
36
|
+
* @param props.avatarSize - Size of the avatar
|
|
37
|
+
* @param props.img - Image URL for the avatar
|
|
38
|
+
* @param props.children - Additional elements to render within the profile component
|
|
39
|
+
* @returns JSX.Element representing a user profile
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* <InlineProfile
|
|
43
|
+
* name="John Doe"
|
|
44
|
+
* secondaryName="johndoe123"
|
|
45
|
+
* partnerName="facebook"
|
|
46
|
+
* partnerLogoLabel="Facebook Logo"
|
|
47
|
+
* avatarSize="24px"
|
|
48
|
+
* img="https://example.com/avatar.jpg"
|
|
49
|
+
* >
|
|
50
|
+
* <Badge text="Moderator" badgeColor="green" />
|
|
51
|
+
* </InlineProfile>
|
|
52
|
+
*/
|
|
53
|
+
declare const InlineProfile: ({ name, secondaryName, partnerName, partnerLogoLabel, avatarSize, img, children, }: TypeInlineProfileProps) => react_jsx_runtime.JSX.Element;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A ProfileToken component that wraps CompactProfile in a Seeds Token component.
|
|
57
|
+
* This token is not closable and provides a compact way to display profile information inline.
|
|
58
|
+
*/
|
|
59
|
+
declare const ProfileToken: React$1.FC<ProfileTokenProps>;
|
|
60
|
+
|
|
61
|
+
export { InlineProfile, ProfileToken, type ProfileTokenProps, type TypeInlineProfileProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { EnumLogoNamesWithoutVariants } from '@sproutsocial/seeds-partner-logos';
|
|
3
|
+
import Token from '@sproutsocial/seeds-react-token';
|
|
4
|
+
import React$1 from 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Profile Component Types
|
|
8
|
+
*
|
|
9
|
+
* This file contains TypeScript interfaces and types for the Profile component
|
|
10
|
+
* that can be used by backend services to render user profile data.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
interface TypeInlineProfileProps {
|
|
14
|
+
name: string;
|
|
15
|
+
secondaryName?: string;
|
|
16
|
+
avatarSize?: string;
|
|
17
|
+
partnerName?: EnumLogoNamesWithoutVariants;
|
|
18
|
+
partnerLogoLabel?: string;
|
|
19
|
+
img?: string;
|
|
20
|
+
children?: React.ReactNode | React.ReactNode[];
|
|
21
|
+
}
|
|
22
|
+
interface ProfileTokenProps extends TypeInlineProfileProps {
|
|
23
|
+
/** Additional CSS class name */
|
|
24
|
+
className?: string;
|
|
25
|
+
/** Additional props to pass to the Token component */
|
|
26
|
+
tokenProps?: Omit<React.ComponentProps<typeof Token>, "children">;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param props - Profile props
|
|
32
|
+
* @param props.name - Name of the profile
|
|
33
|
+
* @param props.secondaryName - Secondary name of the profile
|
|
34
|
+
* @param props.partnerName - Partner logo name
|
|
35
|
+
* @param props.partnerLogoLabel - Aria-label for the partner logo
|
|
36
|
+
* @param props.avatarSize - Size of the avatar
|
|
37
|
+
* @param props.img - Image URL for the avatar
|
|
38
|
+
* @param props.children - Additional elements to render within the profile component
|
|
39
|
+
* @returns JSX.Element representing a user profile
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* <InlineProfile
|
|
43
|
+
* name="John Doe"
|
|
44
|
+
* secondaryName="johndoe123"
|
|
45
|
+
* partnerName="facebook"
|
|
46
|
+
* partnerLogoLabel="Facebook Logo"
|
|
47
|
+
* avatarSize="24px"
|
|
48
|
+
* img="https://example.com/avatar.jpg"
|
|
49
|
+
* >
|
|
50
|
+
* <Badge text="Moderator" badgeColor="green" />
|
|
51
|
+
* </InlineProfile>
|
|
52
|
+
*/
|
|
53
|
+
declare const InlineProfile: ({ name, secondaryName, partnerName, partnerLogoLabel, avatarSize, img, children, }: TypeInlineProfileProps) => react_jsx_runtime.JSX.Element;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A ProfileToken component that wraps CompactProfile in a Seeds Token component.
|
|
57
|
+
* This token is not closable and provides a compact way to display profile information inline.
|
|
58
|
+
*/
|
|
59
|
+
declare const ProfileToken: React$1.FC<ProfileTokenProps>;
|
|
60
|
+
|
|
61
|
+
export { InlineProfile, ProfileToken, type ProfileTokenProps, type TypeInlineProfileProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
InlineProfile: () => InlineProfile,
|
|
34
|
+
ProfileToken: () => ProfileToken
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
|
|
38
|
+
// src/InlineProfile.tsx
|
|
39
|
+
var import_styled_components = __toESM(require("styled-components"));
|
|
40
|
+
var import_seeds_react_text = require("@sproutsocial/seeds-react-text");
|
|
41
|
+
var import_seeds_react_partner_logo = require("@sproutsocial/seeds-react-partner-logo");
|
|
42
|
+
var import_seeds_react_avatar = require("@sproutsocial/seeds-react-avatar");
|
|
43
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
44
|
+
var InlineProfileContainer = import_styled_components.default.div`
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: row;
|
|
47
|
+
align-items: center;
|
|
48
|
+
max-width: 100%;
|
|
49
|
+
`;
|
|
50
|
+
var InlineProfileBody = import_styled_components.default.span`
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
margin-left: 8px;
|
|
54
|
+
`;
|
|
55
|
+
var InlineProfile = ({
|
|
56
|
+
name,
|
|
57
|
+
secondaryName,
|
|
58
|
+
partnerName,
|
|
59
|
+
partnerLogoLabel,
|
|
60
|
+
avatarSize = "22px",
|
|
61
|
+
img,
|
|
62
|
+
children
|
|
63
|
+
}) => {
|
|
64
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InlineProfileContainer, { children: [
|
|
65
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_avatar.Avatar, { size: avatarSize, src: img, name }),
|
|
66
|
+
partnerName && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
67
|
+
import_seeds_react_partner_logo.PartnerLogo,
|
|
68
|
+
{
|
|
69
|
+
size: "small",
|
|
70
|
+
partnerName,
|
|
71
|
+
ml: 300,
|
|
72
|
+
"aria-label": partnerLogoLabel
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_text.Text, { fontSize: 200, fontWeight: "semibold", ml: 300, truncated: true, children: name }),
|
|
76
|
+
secondaryName && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_text.Text, { fontSize: 200, ml: 300, fontWeight: "normal", truncated: true, children: secondaryName }),
|
|
77
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(InlineProfileBody, { children })
|
|
78
|
+
] });
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/ProfileToken.tsx
|
|
82
|
+
var import_react = require("react");
|
|
83
|
+
var import_seeds_react_token = require("@sproutsocial/seeds-react-token");
|
|
84
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
85
|
+
var ProfileToken = ({
|
|
86
|
+
tokenProps,
|
|
87
|
+
className,
|
|
88
|
+
...props
|
|
89
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_token.Token, { className, closeable: false, ...tokenProps, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(InlineProfile, { ...props }) });
|
|
90
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
91
|
+
0 && (module.exports = {
|
|
92
|
+
InlineProfile,
|
|
93
|
+
ProfileToken
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/InlineProfile.tsx","../src/ProfileToken.tsx"],"sourcesContent":["export * from \"./InlineProfile\";\nexport * from \"./ProfileToken\";\nexport * from \"./types\";\n","import styled from \"styled-components\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { PartnerLogo } from \"@sproutsocial/seeds-react-partner-logo\";\nimport { Avatar } from \"@sproutsocial/seeds-react-avatar\";\nimport type { TypeInlineProfileProps } from \"./types\";\n\nconst InlineProfileContainer = styled.div`\n display: flex;\n flex-direction: row;\n align-items: center;\n max-width: 100%;\n`;\n\nconst InlineProfileBody = styled.span`\n display: flex;\n align-items: center;\n margin-left: 8px;\n`;\n\n/**\n *\n * @param props - Profile props\n * @param props.name - Name of the profile\n * @param props.secondaryName - Secondary name of the profile\n * @param props.partnerName - Partner logo name\n * @param props.partnerLogoLabel - Aria-label for the partner logo\n * @param props.avatarSize - Size of the avatar\n * @param props.img - Image URL for the avatar\n * @param props.children - Additional elements to render within the profile component\n * @returns JSX.Element representing a user profile\n *\n * @example\n * <InlineProfile\n * name=\"John Doe\"\n * secondaryName=\"johndoe123\"\n * partnerName=\"facebook\"\n * partnerLogoLabel=\"Facebook Logo\"\n * avatarSize=\"24px\"\n * img=\"https://example.com/avatar.jpg\"\n * >\n * <Badge text=\"Moderator\" badgeColor=\"green\" />\n * </InlineProfile>\n */\nexport const InlineProfile = ({\n name,\n secondaryName,\n partnerName,\n partnerLogoLabel,\n avatarSize = \"22px\",\n img,\n children,\n}: TypeInlineProfileProps) => {\n return (\n <InlineProfileContainer>\n <Avatar size={avatarSize} src={img} name={name} />\n {partnerName && (\n <PartnerLogo\n size=\"small\"\n partnerName={partnerName}\n ml={300}\n aria-label={partnerLogoLabel}\n />\n )}\n <Text fontSize={200} fontWeight=\"semibold\" ml={300} truncated={true}>\n {name}\n </Text>\n {secondaryName && (\n <Text fontSize={200} ml={300} fontWeight=\"normal\" truncated={true}>\n {secondaryName}\n </Text>\n )}\n <InlineProfileBody>{children}</InlineProfileBody>\n </InlineProfileContainer>\n );\n};\n","import React from \"react\";\nimport { Token } from \"@sproutsocial/seeds-react-token\";\nimport { InlineProfile } from \"./InlineProfile\";\nimport type { ProfileTokenProps } from \"./types\";\n\n/**\n * A ProfileToken component that wraps CompactProfile in a Seeds Token component.\n * This token is not closable and provides a compact way to display profile information inline.\n */\nexport const ProfileToken: React.FC<ProfileTokenProps> = ({\n tokenProps,\n className,\n ...props\n}) => (\n <Token className={className} closeable={false} {...tokenProps}>\n <InlineProfile {...props} />\n </Token>\n);\n\nexport default ProfileToken;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,+BAAmB;AACnB,8BAAqB;AACrB,sCAA4B;AAC5B,gCAAuB;AAkDnB;AA/CJ,IAAM,yBAAyB,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,IAAM,oBAAoB,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AA8B1B,IAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AACF,MAA8B;AAC5B,SACE,6CAAC,0BACC;AAAA,gDAAC,oCAAO,MAAM,YAAY,KAAK,KAAK,MAAY;AAAA,IAC/C,eACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,IAAI;AAAA,QACJ,cAAY;AAAA;AAAA,IACd;AAAA,IAEF,4CAAC,gCAAK,UAAU,KAAK,YAAW,YAAW,IAAI,KAAK,WAAW,MAC5D,gBACH;AAAA,IACC,iBACC,4CAAC,gCAAK,UAAU,KAAK,IAAI,KAAK,YAAW,UAAS,WAAW,MAC1D,yBACH;AAAA,IAEF,4CAAC,qBAAmB,UAAS;AAAA,KAC/B;AAEJ;;;AC1EA,mBAAkB;AAClB,+BAAsB;AAclB,IAAAC,sBAAA;AANG,IAAM,eAA4C,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,6CAAC,kCAAM,WAAsB,WAAW,OAAQ,GAAG,YACjD,uDAAC,iBAAe,GAAG,OAAO,GAC5B;","names":["styled","import_jsx_runtime"]}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sproutsocial/seeds-react-profile",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Seeds React Profile",
|
|
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
|
+
"lint": "eslint . --ext .ts,.tsx",
|
|
20
|
+
"lint:fix": "eslint --fix"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@sproutsocial/seeds-react-text": "*",
|
|
24
|
+
"@sproutsocial/seeds-react-avatar": "*",
|
|
25
|
+
"@sproutsocial/seeds-react-partner-logo": "*",
|
|
26
|
+
"@sproutsocial/seeds-react-card": "*",
|
|
27
|
+
"@sproutsocial/seeds-react-token": "*",
|
|
28
|
+
"@sproutsocial/seeds-react-icon": "*"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/react": "^18.0.0",
|
|
32
|
+
"@types/styled-components": "^5.1.26",
|
|
33
|
+
"@sproutsocial/eslint-config-seeds": "*",
|
|
34
|
+
"react": "^18.0.0",
|
|
35
|
+
"styled-components": "^5.2.3",
|
|
36
|
+
"tsup": "^8.3.4",
|
|
37
|
+
"typescript": "^5.6.2",
|
|
38
|
+
"@sproutsocial/seeds-tsconfig": "*",
|
|
39
|
+
"@sproutsocial/seeds-testing": "*",
|
|
40
|
+
"@sproutsocial/seeds-react-testing-library": "*"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"react": "^18.0.0",
|
|
44
|
+
"styled-components": "^5.2.3"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=18"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { InlineProfile } from "./InlineProfile";
|
|
4
|
+
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
5
|
+
|
|
6
|
+
const avatarUrl =
|
|
7
|
+
"https://d672eyudr6aq1.cloudfront.net/avatar/cede1373e17c05542b1cc60f427067f2?s=30&d=404";
|
|
8
|
+
|
|
9
|
+
const VerificationBadge = () => (
|
|
10
|
+
<Icon name="check-solid" style={{ color: "#1da1f2" }} />
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const meta: Meta<typeof InlineProfile> = {
|
|
14
|
+
title: "Components/Profile/InlineProfile",
|
|
15
|
+
component: InlineProfile,
|
|
16
|
+
parameters: {
|
|
17
|
+
layout: "centered",
|
|
18
|
+
},
|
|
19
|
+
tags: ["autodocs"],
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
export const Default: Story = {
|
|
26
|
+
args: {
|
|
27
|
+
name: "John Doe",
|
|
28
|
+
secondaryName: "@johndoe",
|
|
29
|
+
img: avatarUrl,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const WithVerification: Story = {
|
|
34
|
+
args: {
|
|
35
|
+
name: "Elon Musk",
|
|
36
|
+
secondaryName: "@elonmusk",
|
|
37
|
+
img: avatarUrl,
|
|
38
|
+
children: <VerificationBadge />,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const WithPartnerLogo: Story = {
|
|
43
|
+
args: {
|
|
44
|
+
name: "meta",
|
|
45
|
+
secondaryName: "/meta",
|
|
46
|
+
img: avatarUrl,
|
|
47
|
+
partnerName: "facebook",
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const Small: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
name: "small profile",
|
|
54
|
+
secondaryName: "@small",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const Large: Story = {
|
|
59
|
+
args: {
|
|
60
|
+
name: "large profile",
|
|
61
|
+
secondaryName: "@large",
|
|
62
|
+
avatarSize: "32px",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const DifferentNetworks: Story = {
|
|
67
|
+
render: () => (
|
|
68
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
|
69
|
+
<InlineProfile
|
|
70
|
+
name="twitter user"
|
|
71
|
+
secondaryName="@twitteruser"
|
|
72
|
+
img={avatarUrl}
|
|
73
|
+
partnerName="twitter"
|
|
74
|
+
/>
|
|
75
|
+
<InlineProfile
|
|
76
|
+
name="facebook user"
|
|
77
|
+
secondaryName="/facebookuser"
|
|
78
|
+
img={avatarUrl}
|
|
79
|
+
partnerName="facebook"
|
|
80
|
+
/>
|
|
81
|
+
<InlineProfile
|
|
82
|
+
name="instagram user"
|
|
83
|
+
secondaryName="@instagramuser"
|
|
84
|
+
img={avatarUrl}
|
|
85
|
+
partnerName="instagram"
|
|
86
|
+
/>
|
|
87
|
+
<InlineProfile
|
|
88
|
+
name="linkedin user"
|
|
89
|
+
secondaryName="linkedinuser"
|
|
90
|
+
img={avatarUrl}
|
|
91
|
+
partnerName="linkedin"
|
|
92
|
+
/>
|
|
93
|
+
</div>
|
|
94
|
+
),
|
|
95
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Text } from "@sproutsocial/seeds-react-text";
|
|
3
|
+
import { PartnerLogo } from "@sproutsocial/seeds-react-partner-logo";
|
|
4
|
+
import { Avatar } from "@sproutsocial/seeds-react-avatar";
|
|
5
|
+
import type { TypeInlineProfileProps } from "./types";
|
|
6
|
+
|
|
7
|
+
const InlineProfileContainer = styled.div`
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: row;
|
|
10
|
+
align-items: center;
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
const InlineProfileBody = styled.span`
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
margin-left: 8px;
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @param props - Profile props
|
|
23
|
+
* @param props.name - Name of the profile
|
|
24
|
+
* @param props.secondaryName - Secondary name of the profile
|
|
25
|
+
* @param props.partnerName - Partner logo name
|
|
26
|
+
* @param props.partnerLogoLabel - Aria-label for the partner logo
|
|
27
|
+
* @param props.avatarSize - Size of the avatar
|
|
28
|
+
* @param props.img - Image URL for the avatar
|
|
29
|
+
* @param props.children - Additional elements to render within the profile component
|
|
30
|
+
* @returns JSX.Element representing a user profile
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <InlineProfile
|
|
34
|
+
* name="John Doe"
|
|
35
|
+
* secondaryName="johndoe123"
|
|
36
|
+
* partnerName="facebook"
|
|
37
|
+
* partnerLogoLabel="Facebook Logo"
|
|
38
|
+
* avatarSize="24px"
|
|
39
|
+
* img="https://example.com/avatar.jpg"
|
|
40
|
+
* >
|
|
41
|
+
* <Badge text="Moderator" badgeColor="green" />
|
|
42
|
+
* </InlineProfile>
|
|
43
|
+
*/
|
|
44
|
+
export const InlineProfile = ({
|
|
45
|
+
name,
|
|
46
|
+
secondaryName,
|
|
47
|
+
partnerName,
|
|
48
|
+
partnerLogoLabel,
|
|
49
|
+
avatarSize = "22px",
|
|
50
|
+
img,
|
|
51
|
+
children,
|
|
52
|
+
}: TypeInlineProfileProps) => {
|
|
53
|
+
return (
|
|
54
|
+
<InlineProfileContainer>
|
|
55
|
+
<Avatar size={avatarSize} src={img} name={name} />
|
|
56
|
+
{partnerName && (
|
|
57
|
+
<PartnerLogo
|
|
58
|
+
size="small"
|
|
59
|
+
partnerName={partnerName}
|
|
60
|
+
ml={300}
|
|
61
|
+
aria-label={partnerLogoLabel}
|
|
62
|
+
/>
|
|
63
|
+
)}
|
|
64
|
+
<Text fontSize={200} fontWeight="semibold" ml={300} truncated={true}>
|
|
65
|
+
{name}
|
|
66
|
+
</Text>
|
|
67
|
+
{secondaryName && (
|
|
68
|
+
<Text fontSize={200} ml={300} fontWeight="normal" truncated={true}>
|
|
69
|
+
{secondaryName}
|
|
70
|
+
</Text>
|
|
71
|
+
)}
|
|
72
|
+
<InlineProfileBody>{children}</InlineProfileBody>
|
|
73
|
+
</InlineProfileContainer>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { ProfileToken } from "./ProfileToken";
|
|
4
|
+
import { Icon } from "@sproutsocial/seeds-react-icon";
|
|
5
|
+
|
|
6
|
+
const avatarUrl =
|
|
7
|
+
"https://d672eyudr6aq1.cloudfront.net/avatar/cede1373e17c05542b1cc60f427067f2?s=30&d=404";
|
|
8
|
+
|
|
9
|
+
const VerificationBadge = () => (
|
|
10
|
+
<Icon name="check-solid" style={{ color: "#1da1f2" }} />
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const meta: Meta<typeof ProfileToken> = {
|
|
14
|
+
title: "Components/Profile/ProfileToken",
|
|
15
|
+
component: ProfileToken,
|
|
16
|
+
parameters: {
|
|
17
|
+
layout: "centered",
|
|
18
|
+
},
|
|
19
|
+
tags: ["autodocs"],
|
|
20
|
+
argTypes: {},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default meta;
|
|
24
|
+
type Story = StoryObj<typeof meta>;
|
|
25
|
+
|
|
26
|
+
export const Default: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
name: "John Doe",
|
|
29
|
+
secondaryName: "@johndoe",
|
|
30
|
+
img: avatarUrl,
|
|
31
|
+
partnerName: "twitter",
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const WithVerification: Story = {
|
|
36
|
+
args: {
|
|
37
|
+
name: "Elon Musk",
|
|
38
|
+
secondaryName: "@elonmusk",
|
|
39
|
+
img: avatarUrl,
|
|
40
|
+
partnerName: "twitter",
|
|
41
|
+
children: <VerificationBadge />,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const FacebookUser: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
name: "Facebook User",
|
|
48
|
+
secondaryName: "/facebookuser",
|
|
49
|
+
img: avatarUrl,
|
|
50
|
+
partnerName: "facebook",
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const InstagramUser: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
name: "Instagram User",
|
|
57
|
+
secondaryName: "@instagramuser",
|
|
58
|
+
img: avatarUrl,
|
|
59
|
+
partnerName: "instagram",
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const LinkedInUser: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
name: "LinkedIn User",
|
|
66
|
+
secondaryName: "linkedinuser",
|
|
67
|
+
img: avatarUrl,
|
|
68
|
+
partnerName: "linkedin",
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const YouTubeUser: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
name: "YouTube Creator",
|
|
75
|
+
secondaryName: "@youtubecreator",
|
|
76
|
+
img: avatarUrl,
|
|
77
|
+
partnerName: "youtube",
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const TikTokUser: Story = {
|
|
82
|
+
args: {
|
|
83
|
+
name: "TikTok Creator",
|
|
84
|
+
secondaryName: "@tiktokcreator",
|
|
85
|
+
img: avatarUrl,
|
|
86
|
+
partnerName: "tiktok",
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const ThreadsUser: Story = {
|
|
91
|
+
args: {
|
|
92
|
+
name: "Threads User",
|
|
93
|
+
secondaryName: "@threadsuser",
|
|
94
|
+
img: avatarUrl,
|
|
95
|
+
partnerName: "threads",
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const BlueskyUser: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
name: "Bluesky User",
|
|
102
|
+
secondaryName: "@blueskyuser",
|
|
103
|
+
img: avatarUrl,
|
|
104
|
+
partnerName: "bluesky",
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const WithoutAvatar: Story = {
|
|
109
|
+
args: {
|
|
110
|
+
name: "No Avatar User",
|
|
111
|
+
secondaryName: "@noavat,ar",
|
|
112
|
+
partnerName: "twitter",
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const DifferentNetworks: Story = {
|
|
117
|
+
render: () => (
|
|
118
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
|
119
|
+
<ProfileToken
|
|
120
|
+
name="Twitter User"
|
|
121
|
+
secondaryName="@twitteruser"
|
|
122
|
+
img={avatarUrl}
|
|
123
|
+
partnerName="twitter"
|
|
124
|
+
/>
|
|
125
|
+
<ProfileToken
|
|
126
|
+
name="Facebook User"
|
|
127
|
+
secondaryName="/facebookuser"
|
|
128
|
+
img={avatarUrl}
|
|
129
|
+
partnerName="facebook"
|
|
130
|
+
/>
|
|
131
|
+
<ProfileToken
|
|
132
|
+
name="Instagram User"
|
|
133
|
+
secondaryName="@instagramuser"
|
|
134
|
+
img={avatarUrl}
|
|
135
|
+
partnerName="instagram"
|
|
136
|
+
/>
|
|
137
|
+
<ProfileToken
|
|
138
|
+
name="LinkedIn User"
|
|
139
|
+
secondaryName="linkedinuser"
|
|
140
|
+
img={avatarUrl}
|
|
141
|
+
partnerName="linkedin"
|
|
142
|
+
/>
|
|
143
|
+
<ProfileToken
|
|
144
|
+
name="YouTube Creator"
|
|
145
|
+
secondaryName="@youtubecreator"
|
|
146
|
+
img={avatarUrl}
|
|
147
|
+
partnerName="youtube"
|
|
148
|
+
/>
|
|
149
|
+
<ProfileToken
|
|
150
|
+
name="TikTok Creator"
|
|
151
|
+
secondaryName="@tiktokcreator"
|
|
152
|
+
img={avatarUrl}
|
|
153
|
+
partnerName="tiktok"
|
|
154
|
+
/>
|
|
155
|
+
</div>
|
|
156
|
+
),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const TokenVariations: Story = {
|
|
160
|
+
render: () => (
|
|
161
|
+
<div style={{ display: "flex", flexWrap: "wrap", gap: "8px" }}>
|
|
162
|
+
<ProfileToken
|
|
163
|
+
name="Verified User"
|
|
164
|
+
secondaryName="@verified"
|
|
165
|
+
img={avatarUrl}
|
|
166
|
+
partnerName="twitter"
|
|
167
|
+
>
|
|
168
|
+
<VerificationBadge />
|
|
169
|
+
</ProfileToken>
|
|
170
|
+
<ProfileToken
|
|
171
|
+
name="Regular User"
|
|
172
|
+
secondaryName="@regular"
|
|
173
|
+
img={avatarUrl}
|
|
174
|
+
partnerName="twitter"
|
|
175
|
+
/>
|
|
176
|
+
<ProfileToken
|
|
177
|
+
name="Facebook User"
|
|
178
|
+
secondaryName="/facebookuser"
|
|
179
|
+
img={avatarUrl}
|
|
180
|
+
partnerName="facebook"
|
|
181
|
+
/>
|
|
182
|
+
<ProfileToken
|
|
183
|
+
name="Instagram User"
|
|
184
|
+
secondaryName="@instagramuser"
|
|
185
|
+
img={avatarUrl}
|
|
186
|
+
partnerName="instagram"
|
|
187
|
+
/>
|
|
188
|
+
<ProfileToken
|
|
189
|
+
name="LinkedIn User"
|
|
190
|
+
secondaryName="linkedinuser"
|
|
191
|
+
img={avatarUrl}
|
|
192
|
+
partnerName="linkedin"
|
|
193
|
+
/>
|
|
194
|
+
<ProfileToken
|
|
195
|
+
name="YouTube Creator"
|
|
196
|
+
secondaryName="@youtubecreator"
|
|
197
|
+
img={avatarUrl}
|
|
198
|
+
partnerName="youtube"
|
|
199
|
+
/>
|
|
200
|
+
</div>
|
|
201
|
+
),
|
|
202
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Token } from "@sproutsocial/seeds-react-token";
|
|
3
|
+
import { InlineProfile } from "./InlineProfile";
|
|
4
|
+
import type { ProfileTokenProps } from "./types";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A ProfileToken component that wraps CompactProfile in a Seeds Token component.
|
|
8
|
+
* This token is not closable and provides a compact way to display profile information inline.
|
|
9
|
+
*/
|
|
10
|
+
export const ProfileToken: React.FC<ProfileTokenProps> = ({
|
|
11
|
+
tokenProps,
|
|
12
|
+
className,
|
|
13
|
+
...props
|
|
14
|
+
}) => (
|
|
15
|
+
<Token className={className} closeable={false} {...tokenProps}>
|
|
16
|
+
<InlineProfile {...props} />
|
|
17
|
+
</Token>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export default ProfileToken;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@sproutsocial/seeds-react-testing-library";
|
|
3
|
+
import { InlineProfile } from "../InlineProfile";
|
|
4
|
+
|
|
5
|
+
describe("InlineProfile", () => {
|
|
6
|
+
it("renders with name and handle", () => {
|
|
7
|
+
render(
|
|
8
|
+
<InlineProfile
|
|
9
|
+
name="John Doe"
|
|
10
|
+
secondaryName="@johndoe"
|
|
11
|
+
partnerName="twitter"
|
|
12
|
+
img="https://example.com/avatar.jpg"
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(screen.getByText("John Doe")).toBeInTheDocument();
|
|
17
|
+
expect(screen.getByText("@johndoe")).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("renders with children", () => {
|
|
21
|
+
render(
|
|
22
|
+
<InlineProfile
|
|
23
|
+
name="John Doe"
|
|
24
|
+
secondaryName="@johndoe"
|
|
25
|
+
partnerName="twitter"
|
|
26
|
+
img="https://example.com/avatar.jpg"
|
|
27
|
+
>
|
|
28
|
+
Children
|
|
29
|
+
</InlineProfile>
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
expect(screen.getByText("Children")).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("renders network logo", () => {
|
|
36
|
+
render(
|
|
37
|
+
<InlineProfile
|
|
38
|
+
name="John Doe"
|
|
39
|
+
secondaryName="@johndoe"
|
|
40
|
+
partnerName="twitter"
|
|
41
|
+
partnerLogoLabel="Twitter Logo"
|
|
42
|
+
img="https://example.com/avatar.jpg"
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
expect(screen.getByDataQaLabel({ logo: "twitter" })).toBeInTheDocument();
|
|
47
|
+
expect(screen.getByLabelText("Twitter Logo")).toBeInTheDocument();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("renders without network logo when partnerName is not provided", () => {
|
|
51
|
+
render(
|
|
52
|
+
<InlineProfile
|
|
53
|
+
name="John Doe"
|
|
54
|
+
secondaryName="@johndoe"
|
|
55
|
+
img="https://example.com/avatar.jpg"
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
expect(
|
|
60
|
+
screen.queryByDataQaLabel({ logo: "twitter" })
|
|
61
|
+
).not.toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("renders without secondaryName when not provided", () => {
|
|
65
|
+
render(
|
|
66
|
+
<InlineProfile
|
|
67
|
+
name="John Doe"
|
|
68
|
+
partnerName="twitter"
|
|
69
|
+
img="https://example.com/avatar.jpg"
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
expect(screen.getByText("John Doe")).toBeInTheDocument();
|
|
74
|
+
expect(screen.queryByText(/@/)).not.toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("renders avatar with name fallback when img prop is not provided", () => {
|
|
78
|
+
render(<InlineProfile name="John Doe" />);
|
|
79
|
+
|
|
80
|
+
const avatar = screen.getByText("JD");
|
|
81
|
+
expect(avatar).toBeInTheDocument();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@sproutsocial/seeds-react-testing-library";
|
|
3
|
+
import { ProfileToken } from "../ProfileToken";
|
|
4
|
+
|
|
5
|
+
describe("ProfileToken", () => {
|
|
6
|
+
const mockProfileData = {
|
|
7
|
+
name: "John Doe",
|
|
8
|
+
secondaryName: "@johndoe",
|
|
9
|
+
partnerName: "twitter" as const,
|
|
10
|
+
img: "https://example.com/avatar.jpg",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
it("renders profile information in token format", () => {
|
|
14
|
+
render(<ProfileToken {...mockProfileData} />);
|
|
15
|
+
|
|
16
|
+
expect(screen.getByText("John Doe")).toBeInTheDocument();
|
|
17
|
+
expect(screen.getByText("@johndoe")).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("applies custom className", () => {
|
|
21
|
+
const { container } = render(
|
|
22
|
+
<ProfileToken {...mockProfileData} className="custom-token" />
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
26
|
+
expect(container.firstChild).toHaveClass("custom-token");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("renders without close button", () => {
|
|
30
|
+
const { container } = render(<ProfileToken {...mockProfileData} />);
|
|
31
|
+
|
|
32
|
+
// Check that no close button elements are present
|
|
33
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
34
|
+
const closeButtons = container.querySelectorAll(
|
|
35
|
+
'.token-close, .close-button, [data-close], button[aria-label*="close"], button[aria-label*="remove"]'
|
|
36
|
+
);
|
|
37
|
+
expect(closeButtons).toHaveLength(0);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("renders with minimal props", () => {
|
|
41
|
+
render(<ProfileToken name="Jane Smith" />);
|
|
42
|
+
|
|
43
|
+
expect(screen.getByText("Jane Smith")).toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("passes tokenProps to Token component", () => {
|
|
47
|
+
const { container } = render(
|
|
48
|
+
<ProfileToken {...mockProfileData} tokenProps={{ id: "custom-token" }} />
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
52
|
+
expect(container.firstChild).toHaveAttribute("id", "custom-token");
|
|
53
|
+
});
|
|
54
|
+
});
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Component Types
|
|
3
|
+
*
|
|
4
|
+
* This file contains TypeScript interfaces and types for the Profile component
|
|
5
|
+
* that can be used by backend services to render user profile data.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { EnumLogoNamesWithoutVariants } from "@sproutsocial/seeds-partner-logos";
|
|
9
|
+
import type Token from "@sproutsocial/seeds-react-token";
|
|
10
|
+
|
|
11
|
+
export interface TypeInlineProfileProps {
|
|
12
|
+
name: string;
|
|
13
|
+
secondaryName?: string;
|
|
14
|
+
avatarSize?: string;
|
|
15
|
+
partnerName?: EnumLogoNamesWithoutVariants;
|
|
16
|
+
partnerLogoLabel?: string;
|
|
17
|
+
img?: string;
|
|
18
|
+
children?: React.ReactNode | React.ReactNode[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ProfileTokenProps extends TypeInlineProfileProps {
|
|
22
|
+
/** Additional CSS class name */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Additional props to pass to the Token component */
|
|
25
|
+
tokenProps?: Omit<React.ComponentProps<typeof Token>, "children">;
|
|
26
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@sproutsocial/seeds-tsconfig/bundler/dom/library-monorepo",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"jsx": "react-jsx",
|
|
5
|
+
"module": "esnext"
|
|
6
|
+
},
|
|
7
|
+
"include": ["src/**/*"],
|
|
8
|
+
"exclude": [
|
|
9
|
+
"node_modules",
|
|
10
|
+
"dist",
|
|
11
|
+
"coverage",
|
|
12
|
+
"**/*.stories.tsx",
|
|
13
|
+
"**/*.stories.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|
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
|
+
}));
|