@humain/ui 2.1.63 → 2.1.65
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/dist/components/organisms/ai/AIToolCall/AIToolCall.d.ts +9 -3
- package/dist/components/organisms/ai/AIToolRun/index.d.ts +1 -1
- package/dist/components/organisms/ai/AIToolRun/validation.d.ts +24 -3
- package/dist/components/organisms/ai/_shared/format-ai-duration.d.ts +1 -0
- package/dist/components/organisms/ai/_shared/workflow-step-renderer.d.ts +1 -0
- package/dist/index.js +52 -52
- package/dist/index151.js +1 -1
- package/dist/index174.js +7 -339
- package/dist/index174.js.map +1 -1
- package/dist/index175.js +310 -137
- package/dist/index175.js.map +1 -1
- package/dist/index176.js +148 -174
- package/dist/index176.js.map +1 -1
- package/dist/index177.js +186 -78
- package/dist/index177.js.map +1 -1
- package/dist/index178.js +74 -124
- package/dist/index178.js.map +1 -1
- package/dist/index179.js +133 -1
- package/dist/index179.js.map +1 -0
- package/dist/index180.js +2 -201
- package/dist/index181.js +201 -0
- package/dist/{index180.js.map → index181.js.map} +1 -1
- package/dist/index183.js +130 -166
- package/dist/index183.js.map +1 -1
- package/dist/index184.js +195 -983
- package/dist/index184.js.map +1 -1
- package/dist/index185.js +1069 -369
- package/dist/index185.js.map +1 -1
- package/dist/index186.js +395 -197
- package/dist/index186.js.map +1 -1
- package/dist/index187.js +198 -243
- package/dist/index187.js.map +1 -1
- package/dist/index188.js +263 -3
- package/dist/index188.js.map +1 -1
- package/dist/index189.js +3 -209
- package/dist/index189.js.map +1 -1
- package/dist/index190.js +190 -777
- package/dist/index190.js.map +1 -1
- package/dist/index191.js +771 -252
- package/dist/index191.js.map +1 -1
- package/dist/index192.js +250 -65
- package/dist/index192.js.map +1 -1
- package/dist/index193.js +72 -523
- package/dist/index193.js.map +1 -1
- package/dist/index194.js +537 -144
- package/dist/index194.js.map +1 -1
- package/dist/index195.js +139 -720
- package/dist/index195.js.map +1 -1
- package/dist/index196.js +707 -167
- package/dist/index196.js.map +1 -1
- package/dist/index197.js +175 -151
- package/dist/index197.js.map +1 -1
- package/dist/index198.js +152 -487
- package/dist/index198.js.map +1 -1
- package/dist/index199.js +472 -225
- package/dist/index199.js.map +1 -1
- package/dist/index200.js +236 -260
- package/dist/index200.js.map +1 -1
- package/dist/index201.js +265 -215
- package/dist/index201.js.map +1 -1
- package/dist/index202.js +207 -307
- package/dist/index202.js.map +1 -1
- package/dist/index203.js +302 -135
- package/dist/index203.js.map +1 -1
- package/dist/index204.js +140 -271
- package/dist/index204.js.map +1 -1
- package/dist/index205.js +263 -253
- package/dist/index205.js.map +1 -1
- package/dist/index206.js +244 -137
- package/dist/index206.js.map +1 -1
- package/dist/index207.js +100 -238
- package/dist/index207.js.map +1 -1
- package/dist/index208.js +278 -74
- package/dist/index208.js.map +1 -1
- package/dist/index209.js +56 -97
- package/dist/index209.js.map +1 -1
- package/dist/index210.js +142 -47
- package/dist/index210.js.map +1 -1
- package/dist/index211.js +38 -84
- package/dist/index211.js.map +1 -1
- package/dist/index212.js +72 -252
- package/dist/index212.js.map +1 -1
- package/dist/index213.js +274 -26
- package/dist/index213.js.map +1 -1
- package/dist/index214.js +29 -94
- package/dist/index214.js.map +1 -1
- package/dist/index215.js +98 -25
- package/dist/index215.js.map +1 -1
- package/dist/index216.js +20 -565
- package/dist/index216.js.map +1 -1
- package/dist/index217.js +564 -17
- package/dist/index217.js.map +1 -1
- package/dist/index218.js +20 -23
- package/dist/index218.js.map +1 -1
- package/dist/index219.js +20 -95
- package/dist/index219.js.map +1 -1
- package/dist/index220.js +92 -88
- package/dist/index220.js.map +1 -1
- package/dist/index221.js +97 -29
- package/dist/index221.js.map +1 -1
- package/dist/index222.js +24 -470
- package/dist/index222.js.map +1 -1
- package/dist/index223.js +446 -196
- package/dist/index223.js.map +1 -1
- package/dist/index224.js +199 -729
- package/dist/index224.js.map +1 -1
- package/dist/index225.js +750 -61
- package/dist/index225.js.map +1 -1
- package/dist/index226.js +58 -181
- package/dist/index226.js.map +1 -1
- package/dist/index227.js +175 -259
- package/dist/index227.js.map +1 -1
- package/dist/index228.js +246 -172
- package/dist/index228.js.map +1 -1
- package/dist/index229.js +195 -32
- package/dist/index229.js.map +1 -1
- package/dist/index230.js +12 -40
- package/dist/index230.js.map +1 -1
- package/dist/index231.js +23 -26
- package/dist/index231.js.map +1 -1
- package/dist/index232.js +45 -22
- package/dist/index232.js.map +1 -1
- package/dist/index233.js +27 -48
- package/dist/index233.js.map +1 -1
- package/dist/index234.js +52 -26
- package/dist/index234.js.map +1 -1
- package/dist/index235.js +40 -225
- package/dist/index235.js.map +1 -1
- package/dist/index236.js +217 -39
- package/dist/index236.js.map +1 -1
- package/dist/index237.js +50 -0
- package/dist/index237.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/wc/AIToolCall.js +218 -0
- package/dist/wc/AIToolCall.js.map +1 -0
- package/dist/wc/hf-ai-tool-call.js +34 -219
- package/dist/wc/hf-ai-tool-call.js.map +1 -1
- package/dist/wc/hf-ai-tool-run.js +673 -576
- package/dist/wc/hf-ai-tool-run.js.map +1 -1
- package/dist/wc/workflow-step-renderer.js +79 -78
- package/dist/wc/workflow-step-renderer.js.map +1 -1
- package/dist/wc-react/AIToolCall.js +218 -0
- package/dist/wc-react/AIToolCall.js.map +1 -0
- package/dist/wc-react/hf-ai-tool-call.js +32 -217
- package/dist/wc-react/hf-ai-tool-call.js.map +1 -1
- package/dist/wc-react/hf-ai-tool-run.js +698 -601
- package/dist/wc-react/hf-ai-tool-run.js.map +1 -1
- package/dist/wc-react/workflow-step-renderer.js +58 -57
- package/dist/wc-react/workflow-step-renderer.js.map +1 -1
- package/package.json +1 -1
- package/skills/humain-ui/SKILL.md +1 -1
- package/skills/humain-ui-wc/SKILL.md +1 -1
- package/skills/humain-ui-wc.skill +0 -0
- package/skills/humain-ui.skill +0 -0
- package/dist/index182.js +0 -143
- package/dist/index182.js.map +0 -1
- package/dist/wc/wrench.js +0 -10
- package/dist/wc/wrench.js.map +0 -1
- package/dist/wc-react/wrench.js +0 -10
- package/dist/wc-react/wrench.js.map +0 -1
package/dist/index201.js
CHANGED
|
@@ -1,232 +1,282 @@
|
|
|
1
|
-
import { cn
|
|
2
|
-
import {
|
|
1
|
+
import { cn } from "./index2.js";
|
|
2
|
+
import { Button } from "./index5.js";
|
|
3
|
+
import { ScrollArea } from "./index50.js";
|
|
4
|
+
import { Avatar } from "./index70.js";
|
|
3
5
|
import { cva } from "class-variance-authority";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
+
import { BellRing, Calendar, Clock, Settings, X } from "lucide-react";
|
|
7
|
+
import { useMemo } from "react";
|
|
6
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
},
|
|
14
|
-
status: {
|
|
15
|
-
complete: "bg-primary text-primary-foreground shadow-sm",
|
|
16
|
-
active: "bg-primary-foreground border-2 border-primary text-primary shadow-sm",
|
|
17
|
-
incomplete: "bg-accent text-muted-foreground"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
defaultVariants: {
|
|
21
|
-
shape: "rounded",
|
|
22
|
-
status: "incomplete"
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
var stepConnectorVariants = cva("shrink-0 transition-colors duration-200 ease-out motion-reduce:transition-none", {
|
|
26
|
-
variants: {
|
|
27
|
-
orientation: {
|
|
28
|
-
horizontal: "h-0.5 flex-1 min-w-4 mx-2 mt-[18px]",
|
|
29
|
-
vertical: "w-0.5 h-[30px] my-1 ml-[18px]"
|
|
30
|
-
},
|
|
31
|
-
status: {
|
|
32
|
-
complete: "bg-primary",
|
|
33
|
-
incomplete: "bg-border"
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
defaultVariants: {
|
|
37
|
-
orientation: "horizontal",
|
|
38
|
-
status: "incomplete"
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
var stepLabelVariants = cva("text-base leading-6", {
|
|
42
|
-
variants: { status: {
|
|
43
|
-
complete: "text-card-foreground",
|
|
44
|
-
active: "text-card-foreground",
|
|
45
|
-
incomplete: "text-muted-foreground"
|
|
9
|
+
import { motion, useReducedMotion } from "motion/react";
|
|
10
|
+
//#region src/components/organisms/content/NotificationPanel/NotificationPanel.tsx
|
|
11
|
+
var notificationDotVariants = cva("rounded-full shrink-0 bg-primary", {
|
|
12
|
+
variants: { size: {
|
|
13
|
+
sm: "size-2",
|
|
14
|
+
md: "size-2.5"
|
|
46
15
|
} },
|
|
47
|
-
defaultVariants: {
|
|
16
|
+
defaultVariants: { size: "sm" }
|
|
48
17
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
function StepIndicatorContent({ index, status, shape, bulletType }) {
|
|
54
|
-
if (bulletType === "icon") {
|
|
55
|
-
if (status === "complete") return /* @__PURE__ */ jsx(Check, { className: "size-[22px] delight-check-draw" });
|
|
56
|
-
if (status === "active") return /* @__PURE__ */ jsx("div", { className: cn("size-5 bg-primary", shape === "rounded" ? "rounded-sm" : "rounded-full") });
|
|
57
|
-
return /* @__PURE__ */ jsx("div", { className: "size-1.5 rounded-full bg-current" });
|
|
58
|
-
}
|
|
59
|
-
return index + 1;
|
|
60
|
-
}
|
|
61
|
-
function StepIndicator({ index, status, shape, bulletType }) {
|
|
62
|
-
return /* @__PURE__ */ jsx("div", {
|
|
63
|
-
"data-slot": "steps-indicator",
|
|
64
|
-
"aria-hidden": "true",
|
|
65
|
-
className: cn(stepIndicatorVariants({
|
|
66
|
-
shape,
|
|
67
|
-
status
|
|
68
|
-
}), status === "complete" && "delight-check-bounce", status === "active" && "delight-pulse-once"),
|
|
69
|
-
children: /* @__PURE__ */ jsx(StepIndicatorContent, {
|
|
70
|
-
index,
|
|
71
|
-
status,
|
|
72
|
-
shape,
|
|
73
|
-
bulletType
|
|
74
|
-
})
|
|
75
|
-
});
|
|
18
|
+
function getHighlightedSegmentKey(segments, position) {
|
|
19
|
+
const offset = segments.slice(0, position).reduce((total, segment) => total + segment.text.length, 0);
|
|
20
|
+
const segment = segments[position];
|
|
21
|
+
return `${offset}:${segment.highlighted ? "highlight" : "plain"}:${segment.text}`;
|
|
76
22
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return /* @__PURE__ */ jsx("div", {
|
|
80
|
-
"data-slot": "steps-connector",
|
|
81
|
-
"aria-hidden": "true",
|
|
82
|
-
className: cn(stepConnectorVariants({
|
|
83
|
-
orientation,
|
|
84
|
-
status: isComplete ? "complete" : "incomplete"
|
|
85
|
-
}), isComplete && "delight-connector-fill")
|
|
86
|
-
});
|
|
23
|
+
function getNotificationActionKey(action) {
|
|
24
|
+
return `${action.primary ? "primary" : "secondary"}:${action.label}`;
|
|
87
25
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
26
|
+
var notificationItemVariants = {
|
|
27
|
+
hidden: {
|
|
28
|
+
opacity: 0,
|
|
29
|
+
y: 8
|
|
30
|
+
},
|
|
31
|
+
visible: {
|
|
32
|
+
opacity: 1,
|
|
33
|
+
y: 0,
|
|
34
|
+
transition: {
|
|
35
|
+
duration: .2,
|
|
36
|
+
ease: [
|
|
37
|
+
0,
|
|
38
|
+
0,
|
|
39
|
+
.2,
|
|
40
|
+
1
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
function NotificationPanelItem({ avatarSrc, avatarFallback, name, time, title, description, unread = true, showOnlineStatus = true, type = "message", meetingDate, meetingTime, actions, highlightedSegments, onClick, className }) {
|
|
46
|
+
return /* @__PURE__ */ jsxs(motion.li, {
|
|
47
|
+
"data-slot": "notification-panel-item",
|
|
48
|
+
className: cn("relative flex gap-3 items-start w-full rounded-lg list-none", "transition-colors duration-150 ease-out hover:bg-accent/50 motion-reduce:transition-none", className),
|
|
49
|
+
variants: notificationItemVariants,
|
|
50
|
+
children: [/* @__PURE__ */ jsx(Avatar, {
|
|
51
|
+
src: avatarSrc,
|
|
52
|
+
fallback: avatarFallback || name,
|
|
53
|
+
size: "lg",
|
|
54
|
+
indicator: showOnlineStatus ? "online" : void 0,
|
|
55
|
+
className: "shrink-0"
|
|
56
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
57
|
+
className: "flex-1 min-w-0 flex flex-col gap-3",
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsxs("div", {
|
|
60
|
+
className: "flex flex-col gap-1",
|
|
61
|
+
children: [
|
|
62
|
+
/* @__PURE__ */ jsxs("div", {
|
|
63
|
+
className: "flex items-center gap-2 flex-wrap",
|
|
64
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
65
|
+
className: "text-sm font-medium text-secondary-foreground",
|
|
66
|
+
children: name
|
|
67
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
68
|
+
className: "text-xs text-muted-foreground",
|
|
69
|
+
children: time
|
|
70
|
+
})]
|
|
71
|
+
}),
|
|
72
|
+
/* @__PURE__ */ jsxs("div", {
|
|
73
|
+
className: "flex items-center gap-2",
|
|
74
|
+
children: [unread && /* @__PURE__ */ jsx("span", {
|
|
75
|
+
className: cn(notificationDotVariants(), "animate-pulse motion-reduce:animate-none"),
|
|
76
|
+
"aria-hidden": "true"
|
|
77
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
78
|
+
type: "button",
|
|
79
|
+
className: cn("text-sm font-bold text-secondary-foreground text-start", "cursor-pointer bg-transparent border-0 p-0", "after:absolute after:inset-0 after:rounded-lg", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:rounded-sm"),
|
|
80
|
+
onClick,
|
|
81
|
+
"aria-label": [
|
|
82
|
+
unread && "Unread",
|
|
83
|
+
type !== "message" && type,
|
|
84
|
+
"notification:",
|
|
85
|
+
title
|
|
86
|
+
].filter(Boolean).join(" "),
|
|
87
|
+
children: title
|
|
88
|
+
})]
|
|
89
|
+
}),
|
|
90
|
+
description && !highlightedSegments && /* @__PURE__ */ jsx("p", {
|
|
91
|
+
className: "text-sm text-muted-foreground line-clamp-2",
|
|
92
|
+
children: description
|
|
93
|
+
}),
|
|
94
|
+
highlightedSegments && /* @__PURE__ */ jsx("p", {
|
|
95
|
+
className: "text-sm text-muted-foreground line-clamp-2",
|
|
96
|
+
children: highlightedSegments.map((segment, position) => segment.highlighted ? /* @__PURE__ */ jsx("span", {
|
|
97
|
+
className: "font-medium text-primary",
|
|
98
|
+
children: segment.text
|
|
99
|
+
}, getHighlightedSegmentKey(highlightedSegments, position)) : /* @__PURE__ */ jsx("span", { children: segment.text }, getHighlightedSegmentKey(highlightedSegments, position)))
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
}),
|
|
103
|
+
type === "meeting" && (meetingDate || meetingTime) && /* @__PURE__ */ jsxs("div", {
|
|
104
|
+
className: "flex items-center gap-1 flex-wrap",
|
|
105
|
+
children: [meetingDate && /* @__PURE__ */ jsxs("div", {
|
|
106
|
+
className: "flex items-center gap-2 flex-1 min-w-0",
|
|
107
|
+
children: [/* @__PURE__ */ jsx(Calendar, { className: "size-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ jsx("span", {
|
|
108
|
+
className: "text-sm text-muted-foreground truncate",
|
|
109
|
+
children: meetingDate
|
|
110
|
+
})]
|
|
111
|
+
}), meetingTime && /* @__PURE__ */ jsxs("div", {
|
|
112
|
+
className: "flex items-center gap-2 flex-1 min-w-0",
|
|
113
|
+
children: [/* @__PURE__ */ jsx(Clock, { className: "size-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ jsx("span", {
|
|
114
|
+
className: "text-sm text-muted-foreground truncate",
|
|
115
|
+
children: meetingTime
|
|
116
|
+
})]
|
|
117
|
+
})]
|
|
118
|
+
}),
|
|
119
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
120
|
+
className: "flex items-center gap-3 relative z-10",
|
|
121
|
+
children: actions.map((action) => /* @__PURE__ */ jsx(Button, {
|
|
122
|
+
appearance: "link",
|
|
123
|
+
variant: "primary",
|
|
124
|
+
size: "sm",
|
|
125
|
+
className: cn("min-h-11 px-1", action.primary ? "text-primary font-semibold" : "text-secondary-foreground font-semibold"),
|
|
126
|
+
onClick: action.onClick,
|
|
127
|
+
children: action.label
|
|
128
|
+
}, getNotificationActionKey(action)))
|
|
129
|
+
})
|
|
130
|
+
]
|
|
131
|
+
})]
|
|
94
132
|
});
|
|
95
133
|
}
|
|
96
|
-
|
|
97
|
-
function
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
shape: ctx.shape,
|
|
119
|
-
bulletType: ctx.bulletType
|
|
120
|
-
});
|
|
121
|
-
const labelElement = /* @__PURE__ */ jsxs("div", {
|
|
122
|
-
"data-slot": "steps-label",
|
|
123
|
-
className: cn("flex flex-col", isHorizontal ? "items-center gap-0.5 text-center w-0 whitespace-nowrap" : "items-start gap-0.5 ml-2.5"),
|
|
124
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
125
|
-
className: stepLabelVariants({ status }),
|
|
126
|
-
children: label
|
|
127
|
-
}), subtext]
|
|
128
|
-
});
|
|
129
|
-
const content = isHorizontal ? /* @__PURE__ */ jsxs("div", {
|
|
130
|
-
className: "flex w-full items-start",
|
|
131
|
-
children: [connector, /* @__PURE__ */ jsxs("div", {
|
|
132
|
-
className: "flex flex-col items-center",
|
|
133
|
-
children: [indicator, labelElement]
|
|
134
|
+
NotificationPanelItem.displayName = "NotificationPanelItem";
|
|
135
|
+
function NotificationSection({ title, children, className }) {
|
|
136
|
+
const prefersReducedMotion = useReducedMotion();
|
|
137
|
+
const sectionVariants = useMemo(() => ({ visible: { transition: { staggerChildren: prefersReducedMotion ? 0 : .05 } } }), [prefersReducedMotion]);
|
|
138
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
139
|
+
"data-slot": "notification-section",
|
|
140
|
+
className: cn("flex flex-col gap-4", className),
|
|
141
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
142
|
+
className: "flex flex-col gap-3",
|
|
143
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
144
|
+
className: "text-sm font-medium text-secondary-foreground",
|
|
145
|
+
children: title
|
|
146
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
147
|
+
className: "h-px bg-surface-2",
|
|
148
|
+
"aria-hidden": "true"
|
|
149
|
+
})]
|
|
150
|
+
}), /* @__PURE__ */ jsx(motion.ul, {
|
|
151
|
+
className: "flex flex-col gap-6",
|
|
152
|
+
initial: "hidden",
|
|
153
|
+
animate: "visible",
|
|
154
|
+
variants: sectionVariants,
|
|
155
|
+
children
|
|
134
156
|
})]
|
|
135
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
136
|
-
className: "flex flex-col items-start",
|
|
137
|
-
children: [connector, /* @__PURE__ */ jsxs("div", {
|
|
138
|
-
className: "flex items-center",
|
|
139
|
-
children: [indicator, labelElement]
|
|
140
|
-
})]
|
|
141
|
-
});
|
|
142
|
-
const labelText = React.useMemo(() => extractText(label), [label]);
|
|
143
|
-
const statusSuffix = status === "complete" ? ", completed" : status === "active" ? ", current" : "";
|
|
144
|
-
return /* @__PURE__ */ jsx("li", {
|
|
145
|
-
"data-slot": "steps-item",
|
|
146
|
-
"aria-current": status === "active" ? "step" : void 0,
|
|
147
|
-
"aria-label": !handleClick && labelText ? `Step ${index + 1}: ${labelText}${statusSuffix}` : void 0,
|
|
148
|
-
className: cn(isHorizontal && !isFirst && "flex-1", !handleClick && className),
|
|
149
|
-
children: handleClick ? /* @__PURE__ */ jsx("button", {
|
|
150
|
-
type: "button",
|
|
151
|
-
onClick: handleClick,
|
|
152
|
-
"aria-label": `Step ${index + 1}: ${labelText || ""}${statusSuffix}`,
|
|
153
|
-
className: cn("cursor-pointer", isHorizontal && "w-full", className, "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-sm"),
|
|
154
|
-
children: content
|
|
155
|
-
}) : content
|
|
156
157
|
});
|
|
157
158
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
159
|
+
NotificationSection.displayName = "NotificationSection";
|
|
160
|
+
var headerLinkButtonClass = "min-h-11 px-1 text-primary font-normal";
|
|
161
|
+
var notificationPanelVariants = cva("relative flex flex-col overflow-hidden", {
|
|
162
|
+
variants: { variant: {
|
|
163
|
+
desktop: "bg-muted border border-border rounded-3xl shadow-3xl",
|
|
164
|
+
mobile: "bg-background shadow-xl"
|
|
165
|
+
} },
|
|
166
|
+
defaultVariants: { variant: "desktop" }
|
|
167
|
+
});
|
|
168
|
+
function NotificationPanel({ title = "Notifications", variant = "desktop", onSettingsClick, onMarkAllRead, onClearAll, onClose, children, showOverlay = false, width = 573, height = 675, className }) {
|
|
169
|
+
const prefersReducedMotion = useReducedMotion();
|
|
170
|
+
const panelContent = /* @__PURE__ */ jsxs("section", {
|
|
171
|
+
"data-slot": "notification-panel",
|
|
172
|
+
"aria-label": title,
|
|
173
|
+
className: cn(notificationPanelVariants({ variant }), className),
|
|
174
|
+
style: {
|
|
175
|
+
width: variant === "desktop" ? width : "100%",
|
|
176
|
+
maxWidth: "100%",
|
|
177
|
+
height: variant === "desktop" ? height : "100%"
|
|
178
|
+
},
|
|
179
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
180
|
+
className: "flex flex-col pb-4",
|
|
181
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
182
|
+
className: "flex flex-col gap-6 px-6",
|
|
183
|
+
children: [
|
|
184
|
+
/* @__PURE__ */ jsxs("div", {
|
|
185
|
+
className: "flex gap-4 items-start pt-6",
|
|
186
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
187
|
+
className: "shrink-0 size-10 flex items-center justify-center bg-card/60 border border-border rounded-lg shadow-sm",
|
|
188
|
+
children: /* @__PURE__ */ jsx(motion.span, {
|
|
189
|
+
animate: prefersReducedMotion ? void 0 : { rotate: [
|
|
190
|
+
0,
|
|
191
|
+
12,
|
|
192
|
+
-10,
|
|
193
|
+
6,
|
|
194
|
+
-3,
|
|
195
|
+
0
|
|
196
|
+
] },
|
|
197
|
+
transition: {
|
|
198
|
+
duration: .6,
|
|
199
|
+
delay: .3,
|
|
200
|
+
ease: "easeOut"
|
|
201
|
+
},
|
|
202
|
+
className: "flex",
|
|
203
|
+
children: /* @__PURE__ */ jsx(BellRing, { className: "size-5 text-secondary-foreground" })
|
|
204
|
+
})
|
|
205
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
206
|
+
className: "flex-1 flex flex-col gap-0.5 justify-center",
|
|
207
|
+
children: /* @__PURE__ */ jsx("h2", {
|
|
208
|
+
className: "text-xl font-semibold text-foreground",
|
|
209
|
+
children: title
|
|
210
|
+
})
|
|
211
|
+
})]
|
|
212
|
+
}),
|
|
213
|
+
/* @__PURE__ */ jsxs("div", {
|
|
214
|
+
className: "flex items-start justify-between",
|
|
215
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
216
|
+
appearance: "link",
|
|
217
|
+
variant: "primary",
|
|
218
|
+
size: "sm",
|
|
219
|
+
className: headerLinkButtonClass,
|
|
220
|
+
startIcon: /* @__PURE__ */ jsx(Settings, { className: "size-5" }),
|
|
221
|
+
onClick: onSettingsClick,
|
|
222
|
+
children: "Settings"
|
|
223
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
224
|
+
className: "flex items-start gap-1",
|
|
225
|
+
children: [
|
|
226
|
+
/* @__PURE__ */ jsx(Button, {
|
|
227
|
+
appearance: "link",
|
|
228
|
+
variant: "primary",
|
|
229
|
+
size: "sm",
|
|
230
|
+
className: headerLinkButtonClass,
|
|
231
|
+
onClick: onMarkAllRead,
|
|
232
|
+
children: "Mark all read"
|
|
233
|
+
}),
|
|
234
|
+
/* @__PURE__ */ jsx("div", {
|
|
235
|
+
className: "size-6 flex items-center justify-center self-center",
|
|
236
|
+
children: /* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-surface-2" })
|
|
237
|
+
}),
|
|
238
|
+
/* @__PURE__ */ jsx(Button, {
|
|
239
|
+
appearance: "link",
|
|
240
|
+
variant: "primary",
|
|
241
|
+
size: "sm",
|
|
242
|
+
className: headerLinkButtonClass,
|
|
243
|
+
onClick: onClearAll,
|
|
244
|
+
children: "Clear all"
|
|
245
|
+
})
|
|
246
|
+
]
|
|
247
|
+
})]
|
|
248
|
+
}),
|
|
249
|
+
/* @__PURE__ */ jsx(Button, {
|
|
250
|
+
appearance: "ghost",
|
|
251
|
+
variant: "secondary",
|
|
252
|
+
size: "icon",
|
|
253
|
+
"aria-label": "Close notifications",
|
|
254
|
+
className: "absolute top-3 end-4 size-10 text-muted-foreground hover:text-foreground transition-colors duration-150 ease-out [&_svg]:transition-transform [&_svg]:duration-200 [&_svg]:ease-out hover:[&_svg]:rotate-90 motion-reduce:[&_svg]:transition-none",
|
|
255
|
+
onClick: onClose,
|
|
256
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-5" })
|
|
257
|
+
})
|
|
258
|
+
]
|
|
259
|
+
})
|
|
260
|
+
}), /* @__PURE__ */ jsx(ScrollArea, {
|
|
261
|
+
className: "flex-1 min-h-0",
|
|
262
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
263
|
+
className: "flex flex-col gap-4 px-6 pb-6",
|
|
264
|
+
"aria-live": "polite",
|
|
265
|
+
children
|
|
217
266
|
})
|
|
218
|
-
})
|
|
267
|
+
})]
|
|
268
|
+
});
|
|
269
|
+
if (variant === "mobile" && showOverlay) return /* @__PURE__ */ jsxs("div", {
|
|
270
|
+
className: "relative flex items-start ps-6 h-full w-full",
|
|
271
|
+
children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-foreground/70 backdrop-blur" }), /* @__PURE__ */ jsx("div", {
|
|
272
|
+
className: "relative flex-1 h-full",
|
|
273
|
+
children: panelContent
|
|
274
|
+
})]
|
|
219
275
|
});
|
|
276
|
+
return panelContent;
|
|
220
277
|
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* @llms Wizard/workflow progress with horizontal/vertical layout, numbered or icon steps
|
|
224
|
-
*/
|
|
225
|
-
var StepsCompound = Object.assign(Steps, {
|
|
226
|
-
Item: StepsItem,
|
|
227
|
-
Subtext: StepsSubtext
|
|
228
|
-
});
|
|
278
|
+
NotificationPanel.displayName = "NotificationPanel";
|
|
229
279
|
//#endregion
|
|
230
|
-
export {
|
|
280
|
+
export { NotificationPanel, NotificationPanelItem, NotificationSection, notificationDotVariants, notificationPanelVariants };
|
|
231
281
|
|
|
232
282
|
//# sourceMappingURL=index201.js.map
|
package/dist/index201.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index201.js","names":[],"sources":["../src/components/organisms/content/Steps/Steps.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport { Check } from 'lucide-react';\nimport * as React from 'react';\nimport { createSafeContext } from '@/lib/create-safe-context';\nimport { cn, extractText } from '@/lib/utils';\n\n/* -----------------------------------------------------------------------------\n * Types\n * -------------------------------------------------------------------------- */\n\nexport type StepStatus = 'complete' | 'active' | 'incomplete';\n\nexport interface StepData {\n label: string;\n subtext?: string;\n}\n\nexport interface StepsProps {\n /** Steps data for flat API */\n steps?: StepData[];\n /** Current step index (0-based) for flat API */\n currentStep?: number;\n /** Orientation of the steps */\n orientation?: 'horizontal' | 'vertical';\n /** Shape of step indicators */\n shape?: 'rounded' | 'round';\n /** Type of bullet content */\n bulletType?: 'text' | 'icon';\n /** Callback when a step is clicked */\n onStepClick?: (index: number) => void;\n /** Children for compound API */\n children?: React.ReactNode;\n /** Additional className */\n className?: string;\n}\n\nexport interface StepsItemProps {\n /** Override auto-calculated status */\n status?: StepStatus;\n /** Click handler for this step */\n onClick?: () => void;\n /** Step label content */\n children: React.ReactNode;\n /** Additional className */\n className?: string;\n}\n\nexport interface StepsSubtextProps {\n children: React.ReactNode;\n className?: string;\n}\n\n/* -----------------------------------------------------------------------------\n * Variants\n * -------------------------------------------------------------------------- */\n\nconst stepIndicatorVariants = cva(\n 'flex items-center justify-center shrink-0 size-[38px] font-medium text-lg transition-all duration-200 ease-out motion-reduce:transition-none',\n {\n variants: {\n shape: {\n rounded: 'rounded-lg',\n round: 'rounded-full',\n },\n status: {\n complete: 'bg-primary text-primary-foreground shadow-sm',\n active:\n 'bg-primary-foreground border-2 border-primary text-primary shadow-sm',\n incomplete: 'bg-accent text-muted-foreground',\n },\n },\n defaultVariants: {\n shape: 'rounded',\n status: 'incomplete',\n },\n },\n);\n\nconst stepConnectorVariants = cva(\n 'shrink-0 transition-colors duration-200 ease-out motion-reduce:transition-none',\n {\n variants: {\n orientation: {\n // Horizontal: fluid width fills available space; mt-[18px] centers 2px line with 38px indicator\n horizontal: 'h-0.5 flex-1 min-w-4 mx-2 mt-[18px]',\n // Vertical: fixed size, centered under 38px indicator\n vertical: 'w-0.5 h-[30px] my-1 ml-[18px]',\n },\n status: {\n complete: 'bg-primary',\n incomplete: 'bg-border',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n status: 'incomplete',\n },\n },\n);\n\nconst stepLabelVariants = cva('text-base leading-6', {\n variants: {\n status: {\n complete: 'text-card-foreground',\n active: 'text-card-foreground',\n incomplete: 'text-muted-foreground',\n },\n },\n defaultVariants: {\n status: 'incomplete',\n },\n});\n\nconst stepSubtextVariants = cva('text-sm leading-5 text-muted-foreground');\n\n/* -----------------------------------------------------------------------------\n * Context\n * -------------------------------------------------------------------------- */\n\ninterface StepsContextValue {\n orientation: 'horizontal' | 'vertical';\n shape: 'rounded' | 'round';\n bulletType: 'text' | 'icon';\n onStepClick?: (index: number) => void;\n getStepStatus: (index: number) => StepStatus;\n}\n\nconst [StepsContext, useStepsContext] =\n createSafeContext<StepsContextValue>('Steps');\n\n/** Per-item index context — injected by Steps parent via Children.map or flat API */\nconst StepIndexContext = React.createContext<number>(0);\n\n/* -----------------------------------------------------------------------------\n * Sub-components\n * -------------------------------------------------------------------------- */\n\ninterface StepIndicatorProps {\n index: number;\n status: StepStatus;\n shape: 'rounded' | 'round';\n bulletType: 'text' | 'icon';\n}\n\nfunction StepIndicatorContent({\n index,\n status,\n shape,\n bulletType,\n}: StepIndicatorProps) {\n if (bulletType === 'icon') {\n if (status === 'complete') {\n return <Check className=\"size-[22px] delight-check-draw\" />;\n }\n if (status === 'active') {\n return (\n <div\n className={cn(\n 'size-5 bg-primary',\n shape === 'rounded' ? 'rounded-sm' : 'rounded-full',\n )}\n />\n );\n }\n\n return <div className=\"size-1.5 rounded-full bg-current\" />;\n }\n\n return index + 1;\n}\n\nfunction StepIndicator({\n index,\n status,\n shape,\n bulletType,\n}: StepIndicatorProps) {\n return (\n <div\n data-slot=\"steps-indicator\"\n aria-hidden=\"true\"\n className={cn(\n stepIndicatorVariants({ shape, status }),\n status === 'complete' && 'delight-check-bounce',\n status === 'active' && 'delight-pulse-once',\n )}\n >\n <StepIndicatorContent\n index={index}\n status={status}\n shape={shape}\n bulletType={bulletType}\n />\n </div>\n );\n}\n\nStepIndicator.displayName = 'StepIndicator';\n\ninterface StepConnectorProps {\n orientation: 'horizontal' | 'vertical';\n isComplete: boolean;\n}\n\nfunction StepConnector({ orientation, isComplete }: StepConnectorProps) {\n return (\n <div\n data-slot=\"steps-connector\"\n aria-hidden=\"true\"\n className={cn(\n stepConnectorVariants({\n orientation,\n status: isComplete ? 'complete' : 'incomplete',\n }),\n isComplete && 'delight-connector-fill',\n )}\n />\n );\n}\n\nStepConnector.displayName = 'StepConnector';\n\nfunction StepsSubtext({ children, className }: StepsSubtextProps) {\n return (\n <span\n data-slot=\"steps-subtext\"\n className={cn(stepSubtextVariants(), className)}\n >\n {children}\n </span>\n );\n}\n\nStepsSubtext.displayName = 'Steps.Subtext';\n\nfunction StepsItem({\n status: statusOverride,\n onClick,\n children,\n className,\n}: StepsItemProps) {\n const ctx = useStepsContext();\n const index = React.useContext(StepIndexContext);\n const status = statusOverride ?? ctx.getStepStatus(index);\n const isFirst = index === 0;\n const handleClick =\n onClick ?? (ctx.onStepClick ? () => ctx.onStepClick?.(index) : undefined);\n\n // Extract subtext from children\n let label: React.ReactNode = null;\n let subtext: React.ReactNode = null;\n\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child) && child.type === StepsSubtext) {\n subtext = child;\n } else if (child != null && child !== false) {\n label = child;\n }\n });\n\n // Connector colored based on previous step's completion (source step, not destination)\n const prevStepStatus = !isFirst ? ctx.getStepStatus(index - 1) : undefined;\n const connector = !isFirst && (\n <StepConnector\n orientation={ctx.orientation}\n isComplete={prevStepStatus === 'complete'}\n />\n );\n\n const isHorizontal = ctx.orientation === 'horizontal';\n\n // Build indicator element\n const indicator = (\n <StepIndicator\n index={index}\n status={status}\n shape={ctx.shape}\n bulletType={ctx.bulletType}\n />\n );\n\n // Build label element\n // In horizontal mode, w-0 ensures the label doesn't affect the indicator column width.\n // The text overflows visually (centered under the 38px indicator) but the layout\n // width stays fixed, keeping all connectors equally spaced (matching Figma spec).\n const labelElement = (\n <div\n data-slot=\"steps-label\"\n className={cn(\n 'flex flex-col',\n isHorizontal\n ? 'items-center gap-0.5 text-center w-0 whitespace-nowrap'\n : 'items-start gap-0.5 ml-2.5',\n )}\n >\n <span className={stepLabelVariants({ status })}>{label}</span>\n {subtext}\n </div>\n );\n\n // Layout differs by orientation:\n // - Horizontal: connector + (indicator column), items-start so indicators align at top\n // - Vertical: connector above, indicator + label in row\n const content = isHorizontal ? (\n <div className=\"flex w-full items-start\">\n {connector}\n <div className=\"flex flex-col items-center\">\n {indicator}\n {labelElement}\n </div>\n </div>\n ) : (\n <div className=\"flex flex-col items-start\">\n {connector}\n <div className=\"flex items-center\">\n {indicator}\n {labelElement}\n </div>\n </div>\n );\n\n const labelText = React.useMemo(() => extractText(label), [label]);\n const statusSuffix =\n status === 'complete'\n ? ', completed'\n : status === 'active'\n ? ', current'\n : '';\n\n return (\n <li\n data-slot=\"steps-item\"\n aria-current={status === 'active' ? 'step' : undefined}\n aria-label={\n !handleClick && labelText\n ? `Step ${index + 1}: ${labelText}${statusSuffix}`\n : undefined\n }\n className={cn(\n isHorizontal && !isFirst && 'flex-1',\n !handleClick && className,\n )}\n >\n {handleClick ? (\n <button\n type=\"button\"\n onClick={handleClick}\n aria-label={`Step ${index + 1}: ${labelText || ''}${statusSuffix}`}\n className={cn(\n 'cursor-pointer',\n isHorizontal && 'w-full',\n className,\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-sm',\n )}\n >\n {content}\n </button>\n ) : (\n content\n )}\n </li>\n );\n}\n\nStepsItem.displayName = 'Steps.Item';\n\n/* -----------------------------------------------------------------------------\n * Main Component\n * -------------------------------------------------------------------------- */\n\n/**\n * Steps displays a multi-step progress indicator for wizards and workflows.\n * Supports horizontal/vertical orientation, numbered or icon bullets, and clickable steps.\n *\n * @llms Wizard/workflow progress with horizontal/vertical layout, numbered or icon steps\n * @example\n * ```tsx\n * <Steps\n * steps={[{ label: 'Details' }, { label: 'Payment' }, { label: 'Confirm' }]}\n * currentStep={1}\n * orientation=\"horizontal\"\n * />\n * ```\n */\nfunction Steps({\n steps,\n currentStep = 0,\n orientation = 'horizontal',\n shape = 'rounded',\n bulletType = 'text',\n onStepClick,\n children,\n className,\n}: StepsProps) {\n const getStepStatus = React.useCallback(\n (index: number): StepStatus => {\n if (index < currentStep) return 'complete';\n if (index === currentStep) return 'active';\n return 'incomplete';\n },\n [currentStep],\n );\n\n const contextValue = React.useMemo<StepsContextValue>(\n () => ({\n orientation,\n shape,\n bulletType,\n onStepClick,\n getStepStatus,\n }),\n [orientation, shape, bulletType, onStepClick, getStepStatus],\n );\n\n // Determine if using flat API or compound API\n const useCompoundAPI = !steps && React.Children.count(children) > 0;\n\n const renderFlatAPI = () => {\n if (!steps || steps.length === 0) return null;\n\n return steps.map((step, index) => (\n <StepIndexContext.Provider key={`${index}-${step.label}`} value={index}>\n <StepsItem>\n {step.label}\n {step.subtext && <StepsSubtext>{step.subtext}</StepsSubtext>}\n </StepsItem>\n </StepIndexContext.Provider>\n ));\n };\n\n const renderCompoundAPI = () => {\n return React.Children.map(children, (child, index) => (\n <StepIndexContext.Provider value={index}>\n {child}\n </StepIndexContext.Provider>\n ));\n };\n\n return (\n <StepsContext.Provider value={contextValue}>\n <nav\n aria-label=\"Progress steps\"\n data-slot=\"steps\"\n // biome-ignore lint/a11y/noNoninteractiveTabindex: Focusable scroll region satisfies axe scrollable-region-focusable.\n tabIndex={0}\n className={cn(\n 'overflow-x-auto focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n className,\n )}\n >\n <ol\n data-slot=\"steps-list\"\n className={cn(\n 'flex',\n orientation === 'horizontal'\n ? 'flex-row items-start'\n : 'flex-col items-start',\n )}\n >\n {useCompoundAPI ? renderCompoundAPI() : renderFlatAPI()}\n </ol>\n </nav>\n </StepsContext.Provider>\n );\n}\n\nSteps.displayName = 'Steps';\n\n/* -----------------------------------------------------------------------------\n * Compound Export\n * -------------------------------------------------------------------------- */\n\n/**\n * @llms Wizard/workflow progress with horizontal/vertical layout, numbered or icon steps\n */\nexport const StepsCompound = Object.assign(Steps, {\n Item: StepsItem,\n Subtext: StepsSubtext,\n});\n\nexport {\n StepsCompound as Steps,\n StepsItem,\n StepsSubtext,\n stepConnectorVariants,\n stepIndicatorVariants,\n stepLabelVariants,\n stepSubtextVariants,\n};\n"],"mappings":";;;;;;;AAwDA,IAAM,wBAAwB,IAC5B,gJACA;CACE,UAAU;EACR,OAAO;GACL,SAAS;GACT,OAAO;EACT;EACA,QAAQ;GACN,UAAU;GACV,QACE;GACF,YAAY;EACd;CACF;CACA,iBAAiB;EACf,OAAO;EACP,QAAQ;CACV;AACF,CACF;AAEA,IAAM,wBAAwB,IAC5B,kFACA;CACE,UAAU;EACR,aAAa;GAEX,YAAY;GAEZ,UAAU;EACZ;EACA,QAAQ;GACN,UAAU;GACV,YAAY;EACd;CACF;CACA,iBAAiB;EACf,aAAa;EACb,QAAQ;CACV;AACF,CACF;AAEA,IAAM,oBAAoB,IAAI,uBAAuB;CACnD,UAAU,EACR,QAAQ;EACN,UAAU;EACV,QAAQ;EACR,YAAY;CACd,EACF;CACA,iBAAiB,EACf,QAAQ,aACV;AACF,CAAC;AAED,IAAM,sBAAsB,IAAI,yCAAyC;AAczE,IAAM,CAAC,cAAc,mBACnB,kBAAqC,OAAO;;AAG9C,IAAM,mBAAmB,MAAM,cAAsB,CAAC;AAatD,SAAS,qBAAqB,EAC5B,OACA,QACA,OACA,cACqB;CACrB,IAAI,eAAe,QAAQ;EACzB,IAAI,WAAW,YACb,OAAO,oBAAC,OAAD,EAAO,WAAU,iCAAkC,CAAA;EAE5D,IAAI,WAAW,UACb,OACE,oBAAC,OAAD,EACE,WAAW,GACT,qBACA,UAAU,YAAY,eAAe,cACvC,EACD,CAAA;EAIL,OAAO,oBAAC,OAAD,EAAK,WAAU,mCAAoC,CAAA;CAC5D;CAEA,OAAO,QAAQ;AACjB;AAEA,SAAS,cAAc,EACrB,OACA,QACA,OACA,cACqB;CACrB,OACE,oBAAC,OAAD;EACE,aAAU;EACV,eAAY;EACZ,WAAW,GACT,sBAAsB;GAAE;GAAO;EAAO,CAAC,GACvC,WAAW,cAAc,wBACzB,WAAW,YAAY,oBACzB;YAEA,oBAAC,sBAAD;GACS;GACC;GACD;GACK;EACb,CAAA;CACE,CAAA;AAET;AAEA,cAAc,cAAc;AAO5B,SAAS,cAAc,EAAE,aAAa,cAAkC;CACtE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,eAAY;EACZ,WAAW,GACT,sBAAsB;GACpB;GACA,QAAQ,aAAa,aAAa;EACpC,CAAC,GACD,cAAc,wBAChB;CACD,CAAA;AAEL;AAEA,cAAc,cAAc;AAE5B,SAAS,aAAa,EAAE,UAAU,aAAgC;CAChE,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,oBAAoB,GAAG,SAAS;EAE7C;CACG,CAAA;AAEV;AAEA,aAAa,cAAc;AAE3B,SAAS,UAAU,EACjB,QAAQ,gBACR,SACA,UACA,aACiB;CACjB,MAAM,MAAM,gBAAgB;CAC5B,MAAM,QAAQ,MAAM,WAAW,gBAAgB;CAC/C,MAAM,SAAS,kBAAkB,IAAI,cAAc,KAAK;CACxD,MAAM,UAAU,UAAU;CAC1B,MAAM,cACJ,YAAY,IAAI,oBAAoB,IAAI,cAAc,KAAK,IAAI,KAAA;CAGjE,IAAI,QAAyB;CAC7B,IAAI,UAA2B;CAE/B,MAAM,SAAS,QAAQ,WAAW,UAAU;EAC1C,IAAI,MAAM,eAAe,KAAK,KAAK,MAAM,SAAS,cAChD,UAAU;OACL,IAAI,SAAS,QAAQ,UAAU,OACpC,QAAQ;CAEZ,CAAC;CAGD,MAAM,iBAAiB,CAAC,UAAU,IAAI,cAAc,QAAQ,CAAC,IAAI,KAAA;CACjE,MAAM,YAAY,CAAC,WACjB,oBAAC,eAAD;EACE,aAAa,IAAI;EACjB,YAAY,mBAAmB;CAChC,CAAA;CAGH,MAAM,eAAe,IAAI,gBAAgB;CAGzC,MAAM,YACJ,oBAAC,eAAD;EACS;EACC;EACR,OAAO,IAAI;EACX,YAAY,IAAI;CACjB,CAAA;CAOH,MAAM,eACJ,qBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,iBACA,eACI,2DACA,4BACN;YAPF,CASE,oBAAC,QAAD;GAAM,WAAW,kBAAkB,EAAE,OAAO,CAAC;aAAI;EAAY,CAAA,GAC5D,OACE;;CAMP,MAAM,UAAU,eACd,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,WACD,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,WACA,YACE;IACF;MAEL,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,WACD,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,WACA,YACE;IACF;;CAGP,MAAM,YAAY,MAAM,cAAc,YAAY,KAAK,GAAG,CAAC,KAAK,CAAC;CACjE,MAAM,eACJ,WAAW,aACP,gBACA,WAAW,WACT,cACA;CAER,OACE,oBAAC,MAAD;EACE,aAAU;EACV,gBAAc,WAAW,WAAW,SAAS,KAAA;EAC7C,cACE,CAAC,eAAe,YACZ,QAAQ,QAAQ,EAAE,IAAI,YAAY,iBAClC,KAAA;EAEN,WAAW,GACT,gBAAgB,CAAC,WAAW,UAC5B,CAAC,eAAe,SAClB;YAEC,cACC,oBAAC,UAAD;GACE,MAAK;GACL,SAAS;GACT,cAAY,QAAQ,QAAQ,EAAE,IAAI,aAAa,KAAK;GACpD,WAAW,GACT,kBACA,gBAAgB,UAChB,WACA,wJACF;aAEC;EACK,CAAA,IAER;CAEA,CAAA;AAER;AAEA,UAAU,cAAc;;;;;;;;;;;;;;;AAoBxB,SAAS,MAAM,EACb,OACA,cAAc,GACd,cAAc,cACd,QAAQ,WACR,aAAa,QACb,aACA,UACA,aACa;CACb,MAAM,gBAAgB,MAAM,aACzB,UAA8B;EAC7B,IAAI,QAAQ,aAAa,OAAO;EAChC,IAAI,UAAU,aAAa,OAAO;EAClC,OAAO;CACT,GACA,CAAC,WAAW,CACd;CAEA,MAAM,eAAe,MAAM,eAClB;EACL;EACA;EACA;EACA;EACA;CACF,IACA;EAAC;EAAa;EAAO;EAAY;EAAa;CAAa,CAC7D;CAGA,MAAM,iBAAiB,CAAC,SAAS,MAAM,SAAS,MAAM,QAAQ,IAAI;CAElE,MAAM,sBAAsB;EAC1B,IAAI,CAAC,SAAS,MAAM,WAAW,GAAG,OAAO;EAEzC,OAAO,MAAM,KAAK,MAAM,UACtB,oBAAC,iBAAiB,UAAlB;GAA0D,OAAO;aAC/D,qBAAC,WAAD,EAAA,UAAA,CACG,KAAK,OACL,KAAK,WAAW,oBAAC,cAAD,EAAA,UAAe,KAAK,QAAsB,CAAA,CAClD,EAAA,CAAA;EACc,GALK,GAAG,MAAM,GAAG,KAAK,OAKtB,CAC5B;CACH;CAEA,MAAM,0BAA0B;EAC9B,OAAO,MAAM,SAAS,IAAI,WAAW,OAAO,UAC1C,oBAAC,iBAAiB,UAAlB;GAA2B,OAAO;aAC/B;EACwB,CAAA,CAC5B;CACH;CAEA,OACE,oBAAC,aAAa,UAAd;EAAuB,OAAO;YAC5B,oBAAC,OAAD;GACE,cAAW;GACX,aAAU;GAEV,UAAU;GACV,WAAW,GACT,qGACA,SACF;aAEA,oBAAC,MAAD;IACE,aAAU;IACV,WAAW,GACT,QACA,gBAAgB,eACZ,yBACA,sBACN;cAEC,iBAAiB,kBAAkB,IAAI,cAAc;GACpD,CAAA;EACD,CAAA;CACgB,CAAA;AAE3B;AAEA,MAAM,cAAc;;;;AASpB,IAAa,gBAAgB,OAAO,OAAO,OAAO;CAChD,MAAM;CACN,SAAS;AACX,CAAC"}
|
|
1
|
+
{"version":3,"file":"index201.js","names":[],"sources":["../src/components/organisms/content/NotificationPanel/NotificationPanel.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { BellRing, Calendar, Clock, Settings, X } from 'lucide-react';\nimport { motion, useReducedMotion } from 'motion/react';\nimport type * as React from 'react';\nimport { useMemo } from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { ScrollArea } from '@/components/atoms/layout/ScrollArea';\nimport { Avatar } from '@/components/molecules/data/Avatar';\nimport { cn } from '@/lib/utils';\n\n// Notification dot variant\nconst notificationDotVariants = cva('rounded-full shrink-0 bg-primary', {\n variants: {\n size: {\n sm: 'size-2',\n md: 'size-2.5',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n});\n\n// Notification item types\nexport type NotificationPanelItemType =\n | 'message'\n | 'meeting'\n | 'task'\n | 'system';\n\nexport interface NotificationPanelAction {\n /** Label for the action button */\n label: string;\n /** Callback when action is clicked */\n onClick?: () => void;\n /** Whether this is the primary action */\n primary?: boolean;\n}\n\nexport interface NotificationPanelItemProps {\n /** Unique identifier for the notification */\n id: string;\n /** Avatar image source */\n avatarSrc?: string;\n /** Avatar fallback text (for initials) */\n avatarFallback?: string;\n /** Name of the sender/source */\n name: string;\n /** Time since notification was received */\n time: string;\n /** Title/heading of the notification */\n title: string;\n /** Description/body text */\n description?: string;\n /** Whether the notification is unread */\n unread?: boolean;\n /** Show online status indicator on avatar */\n showOnlineStatus?: boolean;\n /** Type of notification */\n type?: NotificationPanelItemType;\n /** Meeting date (for meeting type) */\n meetingDate?: string;\n /** Meeting time (for meeting type) */\n meetingTime?: string;\n /** Actions available for this notification */\n actions?: NotificationPanelAction[];\n /** Highlighted text segments in description */\n highlightedSegments?: Array<{\n text: string;\n highlighted: boolean;\n }>;\n /** Callback when notification item is clicked */\n onClick?: () => void;\n /** Additional CSS classes */\n className?: string;\n}\n\ntype NotificationHighlightedSegment = NonNullable<\n NotificationPanelItemProps['highlightedSegments']\n>[number];\n\nfunction getHighlightedSegmentKey(\n segments: NotificationHighlightedSegment[],\n position: number,\n): React.Key {\n const offset = segments\n .slice(0, position)\n .reduce((total, segment) => total + segment.text.length, 0);\n const segment = segments[position];\n\n return `${offset}:${segment.highlighted ? 'highlight' : 'plain'}:${segment.text}`;\n}\n\nfunction getNotificationActionKey(action: NotificationPanelAction): React.Key {\n return `${action.primary ? 'primary' : 'secondary'}:${action.label}`;\n}\n\nconst notificationItemVariants = {\n hidden: { opacity: 0, y: 8 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.2, ease: [0, 0, 0.2, 1] as const },\n },\n};\n\nfunction NotificationPanelItem({\n avatarSrc,\n avatarFallback,\n name,\n time,\n title,\n description,\n unread = true,\n showOnlineStatus = true,\n type = 'message',\n meetingDate,\n meetingTime,\n actions,\n highlightedSegments,\n onClick,\n className,\n}: NotificationPanelItemProps) {\n return (\n <motion.li\n data-slot=\"notification-panel-item\"\n className={cn(\n 'relative flex gap-3 items-start w-full rounded-lg list-none',\n 'transition-colors duration-150 ease-out hover:bg-accent/50 motion-reduce:transition-none',\n className,\n )}\n variants={notificationItemVariants}\n >\n {/* Avatar */}\n <Avatar\n src={avatarSrc}\n fallback={avatarFallback || name}\n size=\"lg\"\n indicator={showOnlineStatus ? 'online' : undefined}\n className=\"shrink-0\"\n />\n\n {/* Content */}\n <div className=\"flex-1 min-w-0 flex flex-col gap-3\">\n {/* Text content */}\n <div className=\"flex flex-col gap-1\">\n {/* Name and time row */}\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"text-sm font-medium text-secondary-foreground\">\n {name}\n </span>\n <span className=\"text-xs text-muted-foreground\">{time}</span>\n </div>\n\n {/* Title — card-link pattern: button stretches over item via ::after */}\n <div className=\"flex items-center gap-2\">\n {unread && (\n <span\n className={cn(\n notificationDotVariants(),\n 'animate-pulse motion-reduce:animate-none',\n )}\n aria-hidden=\"true\"\n />\n )}\n <button\n type=\"button\"\n className={cn(\n 'text-sm font-bold text-secondary-foreground text-start',\n 'cursor-pointer bg-transparent border-0 p-0',\n 'after:absolute after:inset-0 after:rounded-lg',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:rounded-sm',\n )}\n onClick={onClick}\n aria-label={[\n unread && 'Unread',\n type !== 'message' && type,\n 'notification:',\n title,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {title}\n </button>\n </div>\n\n {/* Description */}\n {description && !highlightedSegments && (\n <p className=\"text-sm text-muted-foreground line-clamp-2\">\n {description}\n </p>\n )}\n\n {/* Highlighted description */}\n {highlightedSegments && (\n <p className=\"text-sm text-muted-foreground line-clamp-2\">\n {highlightedSegments.map((segment, position) =>\n segment.highlighted ? (\n <span\n key={getHighlightedSegmentKey(\n highlightedSegments,\n position,\n )}\n className=\"font-medium text-primary\"\n >\n {segment.text}\n </span>\n ) : (\n <span\n key={getHighlightedSegmentKey(\n highlightedSegments,\n position,\n )}\n >\n {segment.text}\n </span>\n ),\n )}\n </p>\n )}\n </div>\n\n {/* Meeting details (for meeting type) */}\n {type === 'meeting' && (meetingDate || meetingTime) && (\n <div className=\"flex items-center gap-1 flex-wrap\">\n {meetingDate && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Calendar className=\"size-5 text-muted-foreground shrink-0\" />\n <span className=\"text-sm text-muted-foreground truncate\">\n {meetingDate}\n </span>\n </div>\n )}\n {meetingTime && (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Clock className=\"size-5 text-muted-foreground shrink-0\" />\n <span className=\"text-sm text-muted-foreground truncate\">\n {meetingTime}\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Actions — elevated above the card-link overlay */}\n {actions && actions.length > 0 && (\n <div className=\"flex items-center gap-3 relative z-10\">\n {actions.map((action) => (\n <Button\n key={getNotificationActionKey(action)}\n appearance=\"link\"\n variant=\"primary\"\n size=\"sm\"\n className={cn(\n 'min-h-11 px-1',\n action.primary\n ? 'text-primary font-semibold'\n : 'text-secondary-foreground font-semibold',\n )}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n </motion.li>\n );\n}\n\nNotificationPanelItem.displayName = 'NotificationPanelItem';\n\n// Notification section for grouping notifications by date\nexport interface NotificationSectionProps {\n /** Section title (e.g., \"Today\", \"Previous\") */\n title: string;\n /** Notifications in this section */\n children: React.ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction NotificationSection({\n title,\n children,\n className,\n}: NotificationSectionProps) {\n const prefersReducedMotion = useReducedMotion();\n\n const sectionVariants = useMemo(\n () => ({\n visible: {\n transition: {\n staggerChildren: prefersReducedMotion ? 0 : 0.05,\n },\n },\n }),\n [prefersReducedMotion],\n );\n\n return (\n <div\n data-slot=\"notification-section\"\n className={cn('flex flex-col gap-4', className)}\n >\n <div className=\"flex flex-col gap-3\">\n <h3 className=\"text-sm font-medium text-secondary-foreground\">\n {title}\n </h3>\n <div className=\"h-px bg-surface-2\" aria-hidden=\"true\" />\n </div>\n <motion.ul\n className=\"flex flex-col gap-6\"\n initial=\"hidden\"\n animate=\"visible\"\n variants={sectionVariants}\n >\n {children}\n </motion.ul>\n </div>\n );\n}\n\nNotificationSection.displayName = 'NotificationSection';\n\nconst headerLinkButtonClass = 'min-h-11 px-1 text-primary font-normal';\n\n// Main NotificationPanel component\nconst notificationPanelVariants = cva(\n 'relative flex flex-col overflow-hidden',\n {\n variants: {\n variant: {\n desktop: 'bg-muted border border-border rounded-3xl shadow-3xl',\n mobile: 'bg-background shadow-xl',\n },\n },\n defaultVariants: {\n variant: 'desktop',\n },\n },\n);\n\nexport interface NotificationPanelProps\n extends VariantProps<typeof notificationPanelVariants> {\n /** Title of the panel */\n title?: string;\n /** Callback when settings button is clicked */\n onSettingsClick?: () => void;\n /** Callback when \"Mark all read\" is clicked */\n onMarkAllRead?: () => void;\n /** Callback when \"Clear all\" is clicked */\n onClearAll?: () => void;\n /** Callback when close button is clicked */\n onClose?: () => void;\n /** Panel content (NotificationSection or NotificationItem components) */\n children: React.ReactNode;\n /** Whether to show overlay background (mobile variant) */\n showOverlay?: boolean;\n /** Fixed width for desktop variant */\n width?: number;\n /** Fixed height for the panel */\n height?: number;\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction NotificationPanel({\n title = 'Notifications',\n variant = 'desktop',\n onSettingsClick,\n onMarkAllRead,\n onClearAll,\n onClose,\n children,\n showOverlay = false,\n width = 573,\n height = 675,\n className,\n}: NotificationPanelProps) {\n const prefersReducedMotion = useReducedMotion();\n const panelContent = (\n <section\n data-slot=\"notification-panel\"\n aria-label={title}\n className={cn(notificationPanelVariants({ variant }), className)}\n style={{\n width: variant === 'desktop' ? width : '100%',\n maxWidth: '100%',\n height: variant === 'desktop' ? height : '100%',\n }}\n >\n {/* Header */}\n <div className=\"flex flex-col pb-4\">\n <div className=\"flex flex-col gap-6 px-6\">\n {/* Title row */}\n <div className=\"flex gap-4 items-start pt-6\">\n {/* Featured icon */}\n <div className=\"shrink-0 size-10 flex items-center justify-center bg-card/60 border border-border rounded-lg shadow-sm\">\n <motion.span\n animate={\n prefersReducedMotion\n ? undefined\n : { rotate: [0, 12, -10, 6, -3, 0] }\n }\n transition={{ duration: 0.6, delay: 0.3, ease: 'easeOut' }}\n className=\"flex\"\n >\n <BellRing className=\"size-5 text-secondary-foreground\" />\n </motion.span>\n </div>\n {/* Title */}\n <div className=\"flex-1 flex flex-col gap-0.5 justify-center\">\n <h2 className=\"text-xl font-semibold text-foreground\">{title}</h2>\n </div>\n </div>\n\n {/* Actions row */}\n <div className=\"flex items-start justify-between\">\n <Button\n appearance=\"link\"\n variant=\"primary\"\n size=\"sm\"\n className={headerLinkButtonClass}\n startIcon={<Settings className=\"size-5\" />}\n onClick={onSettingsClick}\n >\n Settings\n </Button>\n <div className=\"flex items-start gap-1\">\n <Button\n appearance=\"link\"\n variant=\"primary\"\n size=\"sm\"\n className={headerLinkButtonClass}\n onClick={onMarkAllRead}\n >\n Mark all read\n </Button>\n <div className=\"size-6 flex items-center justify-center self-center\">\n <div className=\"w-px h-5 bg-surface-2\" />\n </div>\n <Button\n appearance=\"link\"\n variant=\"primary\"\n size=\"sm\"\n className={headerLinkButtonClass}\n onClick={onClearAll}\n >\n Clear all\n </Button>\n </div>\n </div>\n\n {/* Close button */}\n <Button\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"icon\"\n aria-label=\"Close notifications\"\n className=\"absolute top-3 end-4 size-10 text-muted-foreground hover:text-foreground transition-colors duration-150 ease-out [&_svg]:transition-transform [&_svg]:duration-200 [&_svg]:ease-out hover:[&_svg]:rotate-90 motion-reduce:[&_svg]:transition-none\"\n onClick={onClose}\n >\n <X className=\"size-5\" />\n </Button>\n </div>\n </div>\n\n {/* Content */}\n <ScrollArea className=\"flex-1 min-h-0\">\n <div className=\"flex flex-col gap-4 px-6 pb-6\" aria-live=\"polite\">\n {children}\n </div>\n </ScrollArea>\n </section>\n );\n\n // For mobile with overlay\n if (variant === 'mobile' && showOverlay) {\n return (\n <div className=\"relative flex items-start ps-6 h-full w-full\">\n {/* Backdrop overlay */}\n <div className=\"absolute inset-0 bg-foreground/70 backdrop-blur\" />\n {/* Panel */}\n <div className=\"relative flex-1 h-full\">{panelContent}</div>\n </div>\n );\n }\n\n return panelContent;\n}\n\nNotificationPanel.displayName = 'NotificationPanel';\n\nexport {\n NotificationPanel,\n NotificationPanelItem,\n NotificationSection,\n notificationDotVariants,\n notificationPanelVariants,\n};\n"],"mappings":"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"}
|