@krrli/cm-designsystem 1.26.0 → 1.27.0

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.
@@ -0,0 +1,76 @@
1
+ import { type VariantProps } from "tailwind-variants";
2
+ declare const profileBannerInfoStyles: import("tailwind-variants").TVReturnType<{
3
+ [key: string]: {
4
+ [key: string]: import("tailwind-merge").ClassNameValue | {
5
+ displayName?: import("tailwind-merge").ClassNameValue;
6
+ base?: import("tailwind-merge").ClassNameValue;
7
+ detailInfo?: import("tailwind-merge").ClassNameValue;
8
+ secondaryInfo?: import("tailwind-merge").ClassNameValue;
9
+ };
10
+ };
11
+ } | {
12
+ [x: string]: {
13
+ [x: string]: import("tailwind-merge").ClassNameValue | {
14
+ displayName?: import("tailwind-merge").ClassNameValue;
15
+ base?: import("tailwind-merge").ClassNameValue;
16
+ detailInfo?: import("tailwind-merge").ClassNameValue;
17
+ secondaryInfo?: import("tailwind-merge").ClassNameValue;
18
+ };
19
+ };
20
+ } | {}, {
21
+ base: string[];
22
+ displayName: string[];
23
+ detailInfo: string[];
24
+ secondaryInfo: string[];
25
+ }, undefined, {
26
+ [key: string]: {
27
+ [key: string]: import("tailwind-merge").ClassNameValue | {
28
+ displayName?: import("tailwind-merge").ClassNameValue;
29
+ base?: import("tailwind-merge").ClassNameValue;
30
+ detailInfo?: import("tailwind-merge").ClassNameValue;
31
+ secondaryInfo?: import("tailwind-merge").ClassNameValue;
32
+ };
33
+ };
34
+ } | {}, {
35
+ base: string[];
36
+ displayName: string[];
37
+ detailInfo: string[];
38
+ secondaryInfo: string[];
39
+ }, import("tailwind-variants").TVReturnType<unknown, {
40
+ base: string[];
41
+ displayName: string[];
42
+ detailInfo: string[];
43
+ secondaryInfo: string[];
44
+ }, undefined, unknown, unknown, undefined>>;
45
+ type ProfileBannerInfoVariants = VariantProps<typeof profileBannerInfoStyles>;
46
+ interface ProfileBannerInfoProps extends ProfileBannerInfoVariants {
47
+ /**
48
+ * The user's full display name (e.g., "John Doe").
49
+ */
50
+ displayName: string;
51
+ /**
52
+ * The user's username or handle (e.g., "@john").
53
+ */
54
+ userName: string;
55
+ /**
56
+ * The user's location as a readable text label.
57
+ */
58
+ location: string;
59
+ /**
60
+ * A timestamp representing when the user joined.
61
+ * Used to generate the "Member since" relative date.
62
+ */
63
+ joinedTimestamp: Date;
64
+ /**
65
+ * Callback fired whenever any profile-related element is clicked.
66
+ * Typically used to open the profile or navigate to a user page.
67
+ */
68
+ onClick: () => void;
69
+ }
70
+ /**
71
+ * ProfileBannerInfo Component
72
+ *
73
+ * Renders profile information used in a user profile banner
74
+ */
75
+ export declare const ProfileBannerInfo: React.FC<ProfileBannerInfoProps>;
76
+ export {};
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { tv } from "tailwind-variants";
3
+ import { IconButton } from "../../components/icon-button/IconButton";
4
+ import { Profile, Location, Calendar } from "../../components/icons/generated";
5
+ import { Label } from "../../components/typography/Label";
6
+ const profileBannerInfoStyles = tv({
7
+ slots: {
8
+ base: ["flex", "flex-col", "gap-2", "items-start"],
9
+ displayName: ["text-slate-900", "**:cursor-pointer"],
10
+ detailInfo: ["flex", "gap-4"],
11
+ secondaryInfo: ["text-slate-500"],
12
+ },
13
+ });
14
+ function timeSince(timestamp) {
15
+ const now = new Date();
16
+ const past = timestamp instanceof Date ? timestamp : new Date(timestamp);
17
+ const diffMs = now.getTime() - past.getTime();
18
+ const seconds = Math.floor(diffMs / 1000);
19
+ const minutes = Math.floor(seconds / 60);
20
+ const hours = Math.floor(minutes / 60);
21
+ const days = Math.floor(hours / 24);
22
+ const months = Math.floor(days / 30); // approximate
23
+ const years = Math.floor(days / 365); // approximate
24
+ if (years > 0)
25
+ return years === 1 ? "1 year" : `${years} years`;
26
+ if (months > 0)
27
+ return months === 1 ? "1 month" : `${months} months`;
28
+ if (days > 0)
29
+ return days === 1 ? "1 day" : `${days} days`;
30
+ if (hours > 0)
31
+ return hours === 1 ? "1 hour" : `${hours} hours`;
32
+ if (minutes > 0)
33
+ return minutes === 1 ? "1 minute" : `${minutes} minutes`;
34
+ return seconds <= 1 ? "just now" : `${seconds} seconds`;
35
+ }
36
+ const memberSincePrefix = "Member since ";
37
+ /**
38
+ * ProfileBannerInfo Component
39
+ *
40
+ * Renders profile information used in a user profile banner
41
+ */
42
+ export const ProfileBannerInfo = (props) => {
43
+ const { base, displayName, detailInfo, secondaryInfo } = profileBannerInfoStyles(props);
44
+ return (_jsxs("div", { className: base(), children: [_jsx("button", { onClick: props.onClick, className: displayName(), children: _jsx(Label, { size: "xl", children: props.displayName }) }), _jsxs("div", { className: detailInfo(), children: [_jsx(IconButton, { intent: "secondary", icon: Profile, onClick: props.onClick, children: props.userName }), _jsx(IconButton, { intent: "primary", icon: Location, onClick: props.onClick, className: secondaryInfo(), children: props.location }), _jsx(IconButton, { intent: "primary", icon: Calendar, onClick: props.onClick, className: secondaryInfo(), children: memberSincePrefix + timeSince(props.joinedTimestamp) })] })] }));
45
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krrli/cm-designsystem",
3
- "version": "1.26.0",
3
+ "version": "1.27.0",
4
4
  "files": [
5
5
  "dist/",
6
6
  "dist/cm-designsystem.css"