@handled-ai/design-system 0.18.36 → 0.18.37
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/charts/chart.d.ts +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/draft-feedback-inline.d.ts +1 -1
- package/dist/components/draft-feedback-inline.js +10 -10
- package/dist/components/draft-feedback-inline.js.map +1 -1
- package/dist/components/email-composer-row.d.ts +11 -0
- package/dist/components/email-composer-row.js +82 -0
- package/dist/components/email-composer-row.js.map +1 -0
- package/dist/components/email-preview-card.d.ts +17 -0
- package/dist/components/email-preview-card.js +71 -0
- package/dist/components/email-preview-card.js.map +1 -0
- package/dist/components/email-recipient-field.d.ts +26 -0
- package/dist/components/email-recipient-field.js +400 -0
- package/dist/components/email-recipient-field.js.map +1 -0
- package/dist/components/email-send-bar.d.ts +22 -0
- package/dist/components/email-send-bar.js +66 -0
- package/dist/components/email-send-bar.js.map +1 -0
- package/dist/components/entity-panel.d.ts +1 -15
- package/dist/components/entity-panel.js +1 -74
- package/dist/components/entity-panel.js.map +1 -1
- package/dist/components/pill.d.ts +1 -1
- package/dist/components/score-feedback.js +6 -6
- package/dist/components/score-feedback.js.map +1 -1
- package/dist/components/suggested-actions.js +5 -17
- package/dist/components/suggested-actions.js.map +1 -1
- package/dist/components/tabs.d.ts +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
- package/src/components/__tests__/email-composer-row.test.tsx +51 -0
- package/src/components/__tests__/email-preview-card.test.tsx +62 -0
- package/src/components/__tests__/email-recipient-field.test.tsx +256 -0
- package/src/components/__tests__/email-send-bar.test.tsx +80 -0
- package/src/components/draft-feedback-inline.tsx +13 -13
- package/src/components/email-composer-row.tsx +47 -0
- package/src/components/email-preview-card.tsx +94 -0
- package/src/components/email-recipient-field.tsx +456 -0
- package/src/components/email-send-bar.tsx +95 -0
- package/src/components/entity-panel.tsx +0 -117
- package/src/components/score-feedback.tsx +7 -7
- package/src/components/suggested-actions.tsx +5 -19
- package/src/index.ts +4 -0
- package/src/components/__tests__/draft-feedback-inline.test.tsx +0 -72
- package/src/components/__tests__/suggested-actions-feedback-header.test.tsx +0 -86
|
@@ -21,10 +21,8 @@ import {
|
|
|
21
21
|
Maximize2,
|
|
22
22
|
Minimize2,
|
|
23
23
|
CalendarDays,
|
|
24
|
-
ChevronRight,
|
|
25
24
|
} from "lucide-react"
|
|
26
25
|
import { TimelineActivity, type TimelineEvent } from "./timeline-activity"
|
|
27
|
-
import { BRAND_ICONS } from "../lib/icons"
|
|
28
26
|
|
|
29
27
|
// ---------------------------------------------------------------------------
|
|
30
28
|
// EntityPanel -- supports Sheet (side panel), wide, and fullscreen modes
|
|
@@ -780,121 +778,6 @@ export function EntityDetails({ onClose: _onClose }: { onClose?: () => void }) {
|
|
|
780
778
|
// SourcesToggle – collapsible sources list
|
|
781
779
|
// ---------------------------------------------------------------------------
|
|
782
780
|
|
|
783
|
-
// ---------------------------------------------------------------------------
|
|
784
|
-
// RelatedRecordActionCard – clickable card for related records (cases, accounts, etc.)
|
|
785
|
-
// ---------------------------------------------------------------------------
|
|
786
|
-
|
|
787
|
-
/** Icon can be a ReactNode (e.g. a Lucide icon) or the string "salesforce" for the brand logo. */
|
|
788
|
-
export type RelatedRecordActionIcon = React.ReactNode | "salesforce"
|
|
789
|
-
|
|
790
|
-
export interface RelatedRecordActionCardProps {
|
|
791
|
-
kind: string
|
|
792
|
-
label: string
|
|
793
|
-
subtitle?: string
|
|
794
|
-
href?: string
|
|
795
|
-
external?: boolean
|
|
796
|
-
icon?: RelatedRecordActionIcon
|
|
797
|
-
onClick?: () => void
|
|
798
|
-
disabledReason?: string
|
|
799
|
-
testId?: string
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
export function RelatedRecordActionCard({
|
|
803
|
-
kind: _kind,
|
|
804
|
-
label,
|
|
805
|
-
subtitle,
|
|
806
|
-
href,
|
|
807
|
-
external,
|
|
808
|
-
icon,
|
|
809
|
-
onClick,
|
|
810
|
-
disabledReason,
|
|
811
|
-
testId,
|
|
812
|
-
}: RelatedRecordActionCardProps) {
|
|
813
|
-
const disabled = !!disabledReason
|
|
814
|
-
|
|
815
|
-
const iconNode =
|
|
816
|
-
icon === "salesforce" ? (
|
|
817
|
-
<img
|
|
818
|
-
src={BRAND_ICONS.salesforce}
|
|
819
|
-
alt="Salesforce"
|
|
820
|
-
className="w-4 h-4 object-contain"
|
|
821
|
-
/>
|
|
822
|
-
) : (
|
|
823
|
-
icon ?? <FileText className="h-4 w-4" aria-hidden="true" />
|
|
824
|
-
)
|
|
825
|
-
|
|
826
|
-
const content = (
|
|
827
|
-
<>
|
|
828
|
-
<div className="flex items-center gap-2.5 min-w-0">
|
|
829
|
-
<div className="w-7 h-7 rounded-md border border-border/60 bg-muted/30 flex items-center justify-center shrink-0 text-muted-foreground">
|
|
830
|
-
{iconNode}
|
|
831
|
-
</div>
|
|
832
|
-
<div className="min-w-0">
|
|
833
|
-
<p className="text-sm font-medium text-foreground leading-snug truncate">
|
|
834
|
-
{label}
|
|
835
|
-
</p>
|
|
836
|
-
{subtitle && (
|
|
837
|
-
<p className="text-[11px] text-muted-foreground/70 truncate">
|
|
838
|
-
{subtitle}
|
|
839
|
-
</p>
|
|
840
|
-
)}
|
|
841
|
-
</div>
|
|
842
|
-
</div>
|
|
843
|
-
<div className="flex items-center gap-1 shrink-0 text-muted-foreground">
|
|
844
|
-
{external && <ExternalLink className="w-3 h-3" />}
|
|
845
|
-
<ChevronRight className="w-3.5 h-3.5" />
|
|
846
|
-
</div>
|
|
847
|
-
</>
|
|
848
|
-
)
|
|
849
|
-
|
|
850
|
-
const baseClassName =
|
|
851
|
-
"flex items-center justify-between gap-3 py-2 px-2 -mx-2 rounded-md transition-colors"
|
|
852
|
-
const interactiveClassName = disabled
|
|
853
|
-
? `${baseClassName} opacity-50 cursor-not-allowed`
|
|
854
|
-
: `${baseClassName} hover:bg-muted/50 cursor-pointer`
|
|
855
|
-
|
|
856
|
-
if (disabled) {
|
|
857
|
-
return (
|
|
858
|
-
<div
|
|
859
|
-
className={interactiveClassName}
|
|
860
|
-
title={disabledReason}
|
|
861
|
-
data-testid={testId}
|
|
862
|
-
>
|
|
863
|
-
{content}
|
|
864
|
-
</div>
|
|
865
|
-
)
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
if (href) {
|
|
869
|
-
return (
|
|
870
|
-
<a
|
|
871
|
-
href={href}
|
|
872
|
-
target={external ? "_blank" : undefined}
|
|
873
|
-
rel={external ? "noopener noreferrer" : undefined}
|
|
874
|
-
className={interactiveClassName}
|
|
875
|
-
data-testid={testId}
|
|
876
|
-
>
|
|
877
|
-
{content}
|
|
878
|
-
</a>
|
|
879
|
-
)
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
return (
|
|
883
|
-
<button
|
|
884
|
-
type="button"
|
|
885
|
-
onClick={onClick}
|
|
886
|
-
className={`${interactiveClassName} w-full text-left`}
|
|
887
|
-
data-testid={testId}
|
|
888
|
-
>
|
|
889
|
-
{content}
|
|
890
|
-
</button>
|
|
891
|
-
)
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
// ---------------------------------------------------------------------------
|
|
895
|
-
// SourcesToggle – collapsible sources list
|
|
896
|
-
// ---------------------------------------------------------------------------
|
|
897
|
-
|
|
898
781
|
function SourcesToggle() {
|
|
899
782
|
const [expanded, setExpanded] = React.useState(false)
|
|
900
783
|
|
|
@@ -149,7 +149,7 @@ function Trigger({ className }: { className?: string }) {
|
|
|
149
149
|
className,
|
|
150
150
|
)}
|
|
151
151
|
>
|
|
152
|
-
<Check className="w-3 h-3 text-
|
|
152
|
+
<Check className="w-3 h-3 text-emerald-500" />
|
|
153
153
|
<span className="text-[11px] text-muted-foreground">{label}</span>
|
|
154
154
|
</button>
|
|
155
155
|
)
|
|
@@ -163,11 +163,11 @@ function Trigger({ className }: { className?: string }) {
|
|
|
163
163
|
className={cn(
|
|
164
164
|
"p-1.5 rounded transition-colors",
|
|
165
165
|
thumbState === "up"
|
|
166
|
-
? "bg-
|
|
166
|
+
? "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400"
|
|
167
167
|
: "hover:bg-muted text-muted-foreground hover:text-foreground"
|
|
168
168
|
)}
|
|
169
169
|
>
|
|
170
|
-
<ThumbsUp className="w-3.5 h-3.5" />
|
|
170
|
+
<ThumbsUp className="w-3.5 h-3.5" fill={thumbState === "up" ? "currentColor" : "none"} />
|
|
171
171
|
</button>
|
|
172
172
|
<button
|
|
173
173
|
type="button"
|
|
@@ -175,11 +175,11 @@ function Trigger({ className }: { className?: string }) {
|
|
|
175
175
|
className={cn(
|
|
176
176
|
"p-1.5 rounded transition-colors",
|
|
177
177
|
thumbState === "down"
|
|
178
|
-
? "bg-
|
|
178
|
+
? "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400"
|
|
179
179
|
: "hover:bg-muted text-muted-foreground hover:text-foreground"
|
|
180
180
|
)}
|
|
181
181
|
>
|
|
182
|
-
<ThumbsDown className="w-3.5 h-3.5" />
|
|
182
|
+
<ThumbsDown className="w-3.5 h-3.5" fill={thumbState === "down" ? "currentColor" : "none"} />
|
|
183
183
|
</button>
|
|
184
184
|
</div>
|
|
185
185
|
)
|
|
@@ -219,8 +219,8 @@ function Panel({ className }: { className?: string }) {
|
|
|
219
219
|
"px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors",
|
|
220
220
|
selectedPills.includes(pill)
|
|
221
221
|
? thumbState === "up"
|
|
222
|
-
? "bg-
|
|
223
|
-
: "bg-red-
|
|
222
|
+
? "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800"
|
|
223
|
+
: "bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800"
|
|
224
224
|
: "bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground"
|
|
225
225
|
)}
|
|
226
226
|
>
|
|
@@ -925,14 +925,6 @@ function SuggestedActionCard({
|
|
|
925
925
|
)
|
|
926
926
|
const [showAiEdit, setShowAiEdit] = React.useState(false)
|
|
927
927
|
const [feedbackOpen, setFeedbackOpen] = React.useState(false)
|
|
928
|
-
const [feedbackDirection, setFeedbackDirection] = React.useState<"up" | "down" | null>(null)
|
|
929
|
-
const handleThumbClick = (dir: "up" | "down") => {
|
|
930
|
-
if (feedbackOpen && feedbackDirection === dir) {
|
|
931
|
-
setFeedbackOpen(false); setFeedbackDirection(null)
|
|
932
|
-
} else {
|
|
933
|
-
setFeedbackDirection(dir); setFeedbackOpen(true)
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
928
|
const [followUpEnabled, setFollowUpEnabled] = React.useState(action.followUp?.enabled ?? false)
|
|
937
929
|
const [threadExpanded, setThreadExpanded] = React.useState(false)
|
|
938
930
|
const [expandedMessageId, setExpandedMessageId] = React.useState<string | null>(null)
|
|
@@ -1024,22 +1016,18 @@ function SuggestedActionCard({
|
|
|
1024
1016
|
</div>
|
|
1025
1017
|
<div className="flex items-center gap-1.5">
|
|
1026
1018
|
<button
|
|
1027
|
-
onClick={() =>
|
|
1019
|
+
onClick={() => setFeedbackOpen(!feedbackOpen)}
|
|
1028
1020
|
className={`p-1.5 rounded transition-colors ${
|
|
1029
|
-
feedbackOpen
|
|
1030
|
-
? "bg-
|
|
1021
|
+
feedbackOpen
|
|
1022
|
+
? "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400"
|
|
1031
1023
|
: "hover:bg-muted text-muted-foreground hover:text-foreground"
|
|
1032
1024
|
}`}
|
|
1033
1025
|
>
|
|
1034
1026
|
<ThumbsUp className="w-3.5 h-3.5" />
|
|
1035
1027
|
</button>
|
|
1036
1028
|
<button
|
|
1037
|
-
onClick={() =>
|
|
1038
|
-
className=
|
|
1039
|
-
feedbackOpen && feedbackDirection === "down"
|
|
1040
|
-
? "bg-muted text-foreground"
|
|
1041
|
-
: "hover:bg-muted text-muted-foreground hover:text-foreground"
|
|
1042
|
-
}`}
|
|
1029
|
+
onClick={() => setFeedbackOpen(!feedbackOpen)}
|
|
1030
|
+
className="p-1.5 rounded transition-colors hover:bg-muted text-muted-foreground hover:text-foreground"
|
|
1043
1031
|
>
|
|
1044
1032
|
<ThumbsDown className="w-3.5 h-3.5" />
|
|
1045
1033
|
</button>
|
|
@@ -1059,8 +1047,6 @@ function SuggestedActionCard({
|
|
|
1059
1047
|
{feedbackOpen && (
|
|
1060
1048
|
<div className="px-5 py-3 border-b border-border/40 animate-in fade-in slide-in-from-top-2 duration-200">
|
|
1061
1049
|
<DraftFeedbackInline
|
|
1062
|
-
key={`feedback-${feedbackDirection}`}
|
|
1063
|
-
initialDirection={feedbackDirection}
|
|
1064
1050
|
onRegenerateRequest={(pills, detail) => {
|
|
1065
1051
|
onFeedback?.("down", pills, detail)
|
|
1066
1052
|
}}
|
package/src/index.ts
CHANGED
|
@@ -40,6 +40,10 @@ export * from "./components/detail-view"
|
|
|
40
40
|
export * from "./components/detail-drawer"
|
|
41
41
|
export * from "./components/dialog"
|
|
42
42
|
export * from "./components/dropdown-menu"
|
|
43
|
+
export * from "./components/email-composer-row"
|
|
44
|
+
export * from "./components/email-preview-card"
|
|
45
|
+
export * from "./components/email-recipient-field"
|
|
46
|
+
export * from "./components/email-send-bar"
|
|
43
47
|
export * from "./components/empty-state"
|
|
44
48
|
export * from "./components/entity-panel"
|
|
45
49
|
export { FeedbackFooter, FeedbackChipGroup, FeedbackInput, FeedbackActions, InlineFeedbackControl } from "./components/feedback-primitives"
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for DraftFeedbackInline.
|
|
3
|
-
*
|
|
4
|
-
* Covers:
|
|
5
|
-
* - Clicking the up thumb activates the positive state (monochrome bg-muted)
|
|
6
|
-
* - Clicking the down thumb activates the negative state (restrained red)
|
|
7
|
-
* - Thumb icons render outline-only (never fill="currentColor")
|
|
8
|
-
* - initialDirection="down" renders the down state pre-selected
|
|
9
|
-
* - initialDirection="up" renders the up state pre-selected
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { describe, it, expect } from "vitest"
|
|
13
|
-
import React from "react"
|
|
14
|
-
import { render, screen, fireEvent } from "@testing-library/react"
|
|
15
|
-
import { DraftFeedbackInline } from "../draft-feedback-inline"
|
|
16
|
-
|
|
17
|
-
describe("DraftFeedbackInline", () => {
|
|
18
|
-
it("renders idle with no expanded feedback area", () => {
|
|
19
|
-
render(<DraftFeedbackInline />)
|
|
20
|
-
expect(screen.getByText("How's this draft?")).toBeTruthy()
|
|
21
|
-
expect(screen.queryByText("What worked well?")).toBeNull()
|
|
22
|
-
expect(screen.queryByText("What needs improvement?")).toBeNull()
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it("activates the positive state with monochrome tokens when up is clicked", () => {
|
|
26
|
-
const { container } = render(<DraftFeedbackInline />)
|
|
27
|
-
const buttons = container.querySelectorAll("button")
|
|
28
|
-
const upButton = buttons[0] as HTMLButtonElement
|
|
29
|
-
fireEvent.click(upButton)
|
|
30
|
-
|
|
31
|
-
expect(screen.getByText("What worked well?")).toBeTruthy()
|
|
32
|
-
expect(upButton.className).toContain("bg-muted")
|
|
33
|
-
expect(upButton.className).toContain("text-foreground")
|
|
34
|
-
expect(upButton.className).not.toContain("emerald")
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it("activates the negative state with restrained red when down is clicked", () => {
|
|
38
|
-
const { container } = render(<DraftFeedbackInline />)
|
|
39
|
-
const buttons = container.querySelectorAll("button")
|
|
40
|
-
const downButton = buttons[1] as HTMLButtonElement
|
|
41
|
-
fireEvent.click(downButton)
|
|
42
|
-
|
|
43
|
-
expect(screen.getByText("What needs improvement?")).toBeTruthy()
|
|
44
|
-
expect(downButton.className).toContain("bg-muted")
|
|
45
|
-
expect(downButton.className).toContain("text-foreground")
|
|
46
|
-
expect(downButton.className).not.toContain("bg-red")
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it("renders thumb icons outline-only (never fill=currentColor)", () => {
|
|
50
|
-
const { container } = render(<DraftFeedbackInline />)
|
|
51
|
-
const buttons = container.querySelectorAll("button")
|
|
52
|
-
// Activate up so the icon would be "filled" under the old behavior.
|
|
53
|
-
fireEvent.click(buttons[0] as HTMLButtonElement)
|
|
54
|
-
|
|
55
|
-
const svgs = container.querySelectorAll("svg")
|
|
56
|
-
svgs.forEach((svg) => {
|
|
57
|
-
expect(svg.getAttribute("fill")).not.toBe("currentColor")
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it("renders the down state pre-selected with initialDirection='down'", () => {
|
|
62
|
-
render(<DraftFeedbackInline initialDirection="down" />)
|
|
63
|
-
expect(screen.getByText("What needs improvement?")).toBeTruthy()
|
|
64
|
-
expect(screen.queryByText("What worked well?")).toBeNull()
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it("renders the up state pre-selected with initialDirection='up'", () => {
|
|
68
|
-
render(<DraftFeedbackInline initialDirection="up" />)
|
|
69
|
-
expect(screen.getByText("What worked well?")).toBeTruthy()
|
|
70
|
-
expect(screen.queryByText("What needs improvement?")).toBeNull()
|
|
71
|
-
})
|
|
72
|
-
})
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for the SuggestedActions card header thumbs (feedback direction).
|
|
3
|
-
*
|
|
4
|
-
* Covers:
|
|
5
|
-
* - Clicking up opens the feedback panel with direction "up"
|
|
6
|
-
* - Clicking down opens the feedback panel with direction "down"
|
|
7
|
-
* - Clicking the same direction again closes the panel
|
|
8
|
-
* - Switching direction remounts DraftFeedbackInline (panel stays open, content switches)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { describe, it, expect } from "vitest"
|
|
12
|
-
import React from "react"
|
|
13
|
-
import { render, screen, fireEvent } from "@testing-library/react"
|
|
14
|
-
import { SuggestedActions } from "../suggested-actions"
|
|
15
|
-
import type { SuggestedAction } from "../suggested-actions"
|
|
16
|
-
|
|
17
|
-
const action: SuggestedAction = {
|
|
18
|
-
id: 1,
|
|
19
|
-
type: "email",
|
|
20
|
-
label: "Send follow-up email",
|
|
21
|
-
status: "pending",
|
|
22
|
-
content: "<p>Hello there.</p>",
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// The header thumbs are the only buttons that wrap a thumbs-up/down SVG and
|
|
26
|
-
// live in the card header. We resolve them by locating the lucide icon class.
|
|
27
|
-
function getHeaderThumbs(container: HTMLElement) {
|
|
28
|
-
const up = container.querySelector("button .lucide-thumbs-up")?.closest("button")
|
|
29
|
-
const down = container.querySelector("button .lucide-thumbs-down")?.closest("button")
|
|
30
|
-
return { up: up as HTMLButtonElement, down: down as HTMLButtonElement }
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe("SuggestedActions header thumbs", () => {
|
|
34
|
-
it("does not show the feedback panel initially", () => {
|
|
35
|
-
render(<SuggestedActions actions={[action]} />)
|
|
36
|
-
expect(screen.queryByText("How's this draft?")).toBeNull()
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it("opens the feedback panel with direction up when up is clicked", () => {
|
|
40
|
-
const { container } = render(<SuggestedActions actions={[action]} />)
|
|
41
|
-
const { up } = getHeaderThumbs(container)
|
|
42
|
-
fireEvent.click(up)
|
|
43
|
-
|
|
44
|
-
expect(screen.getByText("How's this draft?")).toBeTruthy()
|
|
45
|
-
expect(screen.getByText("What worked well?")).toBeTruthy()
|
|
46
|
-
expect(screen.queryByText("What needs improvement?")).toBeNull()
|
|
47
|
-
expect(up.className).toContain("bg-muted")
|
|
48
|
-
expect(up.className).toContain("text-foreground")
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it("opens the feedback panel with direction down when down is clicked", () => {
|
|
52
|
-
const { container } = render(<SuggestedActions actions={[action]} />)
|
|
53
|
-
const { down } = getHeaderThumbs(container)
|
|
54
|
-
fireEvent.click(down)
|
|
55
|
-
|
|
56
|
-
expect(screen.getByText("How's this draft?")).toBeTruthy()
|
|
57
|
-
expect(screen.getByText("What needs improvement?")).toBeTruthy()
|
|
58
|
-
expect(screen.queryByText("What worked well?")).toBeNull()
|
|
59
|
-
expect(down.className).toContain("bg-muted")
|
|
60
|
-
expect(down.className).toContain("text-foreground")
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it("closes the panel when the same direction is clicked again", () => {
|
|
64
|
-
const { container } = render(<SuggestedActions actions={[action]} />)
|
|
65
|
-
const { up } = getHeaderThumbs(container)
|
|
66
|
-
fireEvent.click(up)
|
|
67
|
-
expect(screen.getByText("How's this draft?")).toBeTruthy()
|
|
68
|
-
|
|
69
|
-
fireEvent.click(up)
|
|
70
|
-
expect(screen.queryByText("How's this draft?")).toBeNull()
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it("switches direction (remounts DraftFeedbackInline) while keeping the panel open", () => {
|
|
74
|
-
const { container } = render(<SuggestedActions actions={[action]} />)
|
|
75
|
-
const { up, down } = getHeaderThumbs(container)
|
|
76
|
-
|
|
77
|
-
fireEvent.click(up)
|
|
78
|
-
expect(screen.getByText("What worked well?")).toBeTruthy()
|
|
79
|
-
|
|
80
|
-
fireEvent.click(down)
|
|
81
|
-
// Panel still open, but now showing the negative (down) variant.
|
|
82
|
-
expect(screen.getByText("How's this draft?")).toBeTruthy()
|
|
83
|
-
expect(screen.getByText("What needs improvement?")).toBeTruthy()
|
|
84
|
-
expect(screen.queryByText("What worked well?")).toBeNull()
|
|
85
|
-
})
|
|
86
|
-
})
|