@carlonicora/nextjs-jsonapi 6.27.0 → 6.28.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.
- package/dist/{BlockNoteEditor-D2DXVXTJ.mjs → BlockNoteEditor-2LO34HXR.mjs} +2 -2
- package/dist/{BlockNoteEditor-NQB75M47.js → BlockNoteEditor-SWDRMNLT.js} +9 -9
- package/dist/{BlockNoteEditor-NQB75M47.js.map → BlockNoteEditor-SWDRMNLT.js.map} +1 -1
- package/dist/billing/index.js +378 -378
- package/dist/billing/index.mjs +1 -1
- package/dist/{chunk-YGV27OAW.js → chunk-6RWEYSYE.js} +27 -5
- package/dist/chunk-6RWEYSYE.js.map +1 -0
- package/dist/{chunk-HU3AGUFI.mjs → chunk-NV3NNNS6.mjs} +27 -5
- package/dist/chunk-NV3NNNS6.mjs.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/containers/RoundPageContainer.d.ts +3 -1
- package/dist/components/containers/RoundPageContainer.d.ts.map +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/index.mjs +1 -1
- package/dist/components/typography/DetailField.d.ts +3 -1
- package/dist/components/typography/DetailField.d.ts.map +1 -1
- package/dist/contexts/index.js +2 -2
- package/dist/contexts/index.mjs +1 -1
- package/dist/email-automations/index.js +78 -78
- package/dist/email-automations/index.mjs +1 -1
- package/dist/features/analytics/index.js +107 -107
- package/dist/features/analytics/index.mjs +1 -1
- package/dist/features/blog/index.js +93 -93
- package/dist/features/blog/index.mjs +1 -1
- package/dist/features/help/index.js +31 -31
- package/dist/features/help/index.mjs +1 -1
- package/dist/features/tokenusage/index.js +102 -102
- package/dist/features/tokenusage/index.mjs +1 -1
- package/package.json +1 -1
- package/src/components/containers/RoundPageContainer.tsx +21 -2
- package/src/components/containers/__tests__/RoundPageContainer.detailsSurface.spec.tsx +82 -0
- package/src/components/typography/DetailField.tsx +4 -1
- package/src/components/typography/__tests__/DetailField.spec.tsx +13 -0
- package/dist/chunk-HU3AGUFI.mjs.map +0 -1
- package/dist/chunk-YGV27OAW.js.map +0 -1
- /package/dist/{BlockNoteEditor-D2DXVXTJ.mjs.map → BlockNoteEditor-2LO34HXR.mjs.map} +0 -0
|
@@ -119,6 +119,8 @@ type RoundPageContainerProps = {
|
|
|
119
119
|
* navigation — an "info" icon actively misdescribes a conversation list.
|
|
120
120
|
*/
|
|
121
121
|
detailsIcon?: ReactNode;
|
|
122
|
+
/** Paints the details panel on the recessed surface so cards inside it read as cards. Default "default" (unchanged). */
|
|
123
|
+
detailsSurface?: "default" | "muted";
|
|
122
124
|
/**
|
|
123
125
|
* Which element scrolls the page.
|
|
124
126
|
* - `"document"` (default) — the shell's height only FLOORS at the viewport
|
|
@@ -187,6 +189,7 @@ export function RoundPageContainer({
|
|
|
187
189
|
defaultDetailsOpen = false,
|
|
188
190
|
detailsTitle,
|
|
189
191
|
detailsIcon,
|
|
192
|
+
detailsSurface = "default",
|
|
190
193
|
scroll = "fixed",
|
|
191
194
|
}: RoundPageContainerProps) {
|
|
192
195
|
const t = useTranslations();
|
|
@@ -702,7 +705,15 @@ export function RoundPageContainer({
|
|
|
702
705
|
<SheetHeader>
|
|
703
706
|
<SheetTitle>{detailsTitle ?? t("ui.labels.details")}</SheetTitle>
|
|
704
707
|
</SheetHeader>
|
|
705
|
-
<div
|
|
708
|
+
<div
|
|
709
|
+
data-slot="details-body"
|
|
710
|
+
className={cn(
|
|
711
|
+
"overflow-y-auto",
|
|
712
|
+
detailsSurface === "muted" ? "bg-muted dark:bg-background p-3" : "p-6 pt-0",
|
|
713
|
+
)}
|
|
714
|
+
>
|
|
715
|
+
{details}
|
|
716
|
+
</div>
|
|
706
717
|
</SheetContent>
|
|
707
718
|
</Sheet>
|
|
708
719
|
) : (
|
|
@@ -739,7 +750,15 @@ export function RoundPageContainer({
|
|
|
739
750
|
</div>
|
|
740
751
|
</div>
|
|
741
752
|
)}
|
|
742
|
-
<div
|
|
753
|
+
<div
|
|
754
|
+
data-slot="details-body"
|
|
755
|
+
className={cn(
|
|
756
|
+
"min-h-0 flex-1 overflow-y-auto",
|
|
757
|
+
detailsSurface === "muted" ? "bg-muted dark:bg-background p-3" : "p-4",
|
|
758
|
+
)}
|
|
759
|
+
>
|
|
760
|
+
{details}
|
|
761
|
+
</div>
|
|
743
762
|
</div>
|
|
744
763
|
))}
|
|
745
764
|
</div>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { render, screen } from "@testing-library/react";
|
|
2
|
+
import { beforeAll, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { SharedProvider } from "../../../contexts/SharedContext";
|
|
4
|
+
import { configureI18n } from "../../../i18n";
|
|
5
|
+
import { RoundPageContainer } from "../../containers/RoundPageContainer";
|
|
6
|
+
|
|
7
|
+
vi.mock("next/navigation", () => ({
|
|
8
|
+
usePathname: () => "/",
|
|
9
|
+
useRouter: () => ({
|
|
10
|
+
push: vi.fn(),
|
|
11
|
+
replace: vi.fn(),
|
|
12
|
+
prefetch: vi.fn(),
|
|
13
|
+
back: vi.fn(),
|
|
14
|
+
forward: vi.fn(),
|
|
15
|
+
refresh: vi.fn(),
|
|
16
|
+
}),
|
|
17
|
+
useSearchParams: () => new URLSearchParams(),
|
|
18
|
+
useParams: () => ({}),
|
|
19
|
+
redirect: vi.fn(),
|
|
20
|
+
notFound: vi.fn(),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
beforeAll(() => {
|
|
24
|
+
configureI18n({
|
|
25
|
+
useRouter: () => ({
|
|
26
|
+
push: vi.fn(),
|
|
27
|
+
replace: vi.fn(),
|
|
28
|
+
back: vi.fn(),
|
|
29
|
+
forward: vi.fn(),
|
|
30
|
+
refresh: vi.fn(),
|
|
31
|
+
prefetch: vi.fn(),
|
|
32
|
+
}),
|
|
33
|
+
useTranslations: () => (key: string) => key,
|
|
34
|
+
usePathname: () => "/",
|
|
35
|
+
Link: ({ href, children, ...rest }: { href: string; children: React.ReactNode; [key: string]: any }) => (
|
|
36
|
+
<a href={href} {...rest}>
|
|
37
|
+
{children}
|
|
38
|
+
</a>
|
|
39
|
+
),
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
function withShared(node: React.ReactNode) {
|
|
44
|
+
return <SharedProvider value={{ breadcrumbs: [], title: { type: "" } }}>{node}</SharedProvider>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function detailsBody(): Promise<HTMLElement> {
|
|
48
|
+
const content = await screen.findByText("d");
|
|
49
|
+
const body = content.closest<HTMLElement>('[data-slot="details-body"]');
|
|
50
|
+
if (!body) throw new Error("details body not found");
|
|
51
|
+
return body;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
describe("RoundPageContainer details surface", () => {
|
|
55
|
+
it("default surface keeps the details body unpainted with p-4", async () => {
|
|
56
|
+
render(
|
|
57
|
+
withShared(
|
|
58
|
+
<RoundPageContainer testId="shell" details={<div>d</div>} defaultDetailsOpen>
|
|
59
|
+
content
|
|
60
|
+
</RoundPageContainer>,
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
const body = await detailsBody();
|
|
64
|
+
expect(body.classList.contains("p-4")).toBe(true);
|
|
65
|
+
expect(body.classList.contains("bg-muted")).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("muted surface paints the details body", async () => {
|
|
69
|
+
render(
|
|
70
|
+
withShared(
|
|
71
|
+
<RoundPageContainer testId="shell" details={<div>d</div>} defaultDetailsOpen detailsSurface="muted">
|
|
72
|
+
content
|
|
73
|
+
</RoundPageContainer>,
|
|
74
|
+
),
|
|
75
|
+
);
|
|
76
|
+
const body = await detailsBody();
|
|
77
|
+
expect(body.classList.contains("bg-muted")).toBe(true);
|
|
78
|
+
expect(body.classList.contains("dark:bg-background")).toBe(true);
|
|
79
|
+
expect(body.classList.contains("p-3")).toBe(true);
|
|
80
|
+
expect(body.classList.contains("p-4")).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -6,6 +6,8 @@ type DetailFieldProps = React.ComponentProps<"div"> & {
|
|
|
6
6
|
value?: React.ReactNode;
|
|
7
7
|
horizontal?: boolean;
|
|
8
8
|
labelWidth?: string;
|
|
9
|
+
/** Extra classes for the value element (e.g. "min-w-0 flex-1 break-words" so long values wrap in a horizontal row). */
|
|
10
|
+
valueClassName?: string;
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
function DetailField({
|
|
@@ -13,6 +15,7 @@ function DetailField({
|
|
|
13
15
|
value,
|
|
14
16
|
horizontal = false,
|
|
15
17
|
labelWidth,
|
|
18
|
+
valueClassName,
|
|
16
19
|
className,
|
|
17
20
|
children,
|
|
18
21
|
...props
|
|
@@ -26,7 +29,7 @@ function DetailField({
|
|
|
26
29
|
<span className={cn("text-muted-foreground text-xs", horizontal && labelWidth && cn("shrink-0", labelWidth))}>
|
|
27
30
|
{label}
|
|
28
31
|
</span>
|
|
29
|
-
<div className="text-sm">{value ?? children}</div>
|
|
32
|
+
<div className={cn("text-sm", valueClassName)}>{value ?? children}</div>
|
|
30
33
|
</div>
|
|
31
34
|
);
|
|
32
35
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { render, screen } from "@testing-library/react";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { DetailField } from "../DetailField";
|
|
4
|
+
|
|
5
|
+
describe("DetailField", () => {
|
|
6
|
+
it("valueClassName lands on the value element", () => {
|
|
7
|
+
render(<DetailField horizontal label="L" value="V" valueClassName="min-w-0 flex-1" />);
|
|
8
|
+
const value = screen.getByText("V");
|
|
9
|
+
expect(value.classList.contains("text-sm")).toBe(true);
|
|
10
|
+
expect(value.classList.contains("min-w-0")).toBe(true);
|
|
11
|
+
expect(value.classList.contains("flex-1")).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
});
|