@burdenoff/website-sdk 2026.703.2 → 2026.709.2
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/electron-download.d.mts +32 -0
- package/dist/components/electron-download.d.ts +32 -0
- package/dist/components/electron-download.js +131 -0
- package/dist/components/electron-download.js.map +1 -0
- package/dist/components/electron-download.mjs +108 -0
- package/dist/components/electron-download.mjs.map +1 -0
- package/dist/components/launch-countdown.d.mts +15 -0
- package/dist/components/launch-countdown.d.ts +15 -0
- package/dist/components/launch-countdown.js +89 -0
- package/dist/components/launch-countdown.js.map +1 -0
- package/dist/components/launch-countdown.mjs +87 -0
- package/dist/components/launch-countdown.mjs.map +1 -0
- package/dist/components/problems-solved.d.mts +37 -0
- package/dist/components/problems-solved.d.ts +37 -0
- package/dist/components/problems-solved.js +157 -0
- package/dist/components/problems-solved.js.map +1 -0
- package/dist/components/problems-solved.mjs +135 -0
- package/dist/components/problems-solved.mjs.map +1 -0
- package/dist/components/website-switcher.d.mts +27 -0
- package/dist/components/website-switcher.d.ts +27 -0
- package/dist/components/website-switcher.js +168 -0
- package/dist/components/website-switcher.js.map +1 -0
- package/dist/components/website-switcher.mjs +146 -0
- package/dist/components/website-switcher.mjs.map +1 -0
- package/dist/content/index.d.mts +24 -1
- package/dist/content/index.d.ts +24 -1
- package/dist/content/index.js +459 -149
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +378 -87
- package/dist/content/index.mjs.map +1 -1
- package/dist/index.d.mts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +817 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +812 -88
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
|
+
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
|
4
|
+
import { Globe, ChevronDown, Search } from 'lucide-react';
|
|
5
|
+
import { clsx } from 'clsx';
|
|
6
|
+
import { twMerge } from 'tailwind-merge';
|
|
7
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return twMerge(clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
var Input = React.forwardRef(
|
|
13
|
+
({ className, type, ...props }, ref) => {
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
"input",
|
|
16
|
+
{
|
|
17
|
+
type,
|
|
18
|
+
className: cn(
|
|
19
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
20
|
+
className
|
|
21
|
+
),
|
|
22
|
+
ref,
|
|
23
|
+
...props
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
Input.displayName = "Input";
|
|
29
|
+
function normalizeSearch(value) {
|
|
30
|
+
return value.toLowerCase().trim();
|
|
31
|
+
}
|
|
32
|
+
function filterProducts(products, query) {
|
|
33
|
+
const normalized = normalizeSearch(query);
|
|
34
|
+
if (!normalized) return products;
|
|
35
|
+
return products.filter((p) => normalizeSearch(p.name).includes(normalized));
|
|
36
|
+
}
|
|
37
|
+
function WebsiteSwitcher({
|
|
38
|
+
products,
|
|
39
|
+
triggerLabel = "Explore products",
|
|
40
|
+
searchPlaceholder = "Find a product\u2026",
|
|
41
|
+
emptyText = "No products match your search.",
|
|
42
|
+
className
|
|
43
|
+
}) {
|
|
44
|
+
const [open, setOpen] = useState(false);
|
|
45
|
+
const [query, setQuery] = useState("");
|
|
46
|
+
const filtered = useMemo(
|
|
47
|
+
() => filterProducts(products, query),
|
|
48
|
+
[products, query]
|
|
49
|
+
);
|
|
50
|
+
return /* @__PURE__ */ jsxs(DropdownMenu.Root, { open, onOpenChange: setOpen, children: [
|
|
51
|
+
/* @__PURE__ */ jsxs(
|
|
52
|
+
DropdownMenu.Trigger,
|
|
53
|
+
{
|
|
54
|
+
className: cn(
|
|
55
|
+
"inline-flex items-center gap-1.5 text-sm font-medium transition-colors",
|
|
56
|
+
"text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded-md",
|
|
57
|
+
className
|
|
58
|
+
),
|
|
59
|
+
"aria-label": triggerLabel,
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ jsx(Globe, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
62
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: triggerLabel }),
|
|
63
|
+
/* @__PURE__ */ jsx(
|
|
64
|
+
ChevronDown,
|
|
65
|
+
{
|
|
66
|
+
className: cn(
|
|
67
|
+
"h-3.5 w-3.5 transition-transform duration-200",
|
|
68
|
+
open && "rotate-180"
|
|
69
|
+
),
|
|
70
|
+
"aria-hidden": "true"
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
/* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsxs(
|
|
77
|
+
DropdownMenu.Content,
|
|
78
|
+
{
|
|
79
|
+
className: "z-50 min-w-[16rem] max-w-[20rem] rounded-lg border border-border/60 bg-popover p-2 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2",
|
|
80
|
+
sideOffset: 8,
|
|
81
|
+
align: "end",
|
|
82
|
+
avoidCollisions: true,
|
|
83
|
+
children: [
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: "px-2 pb-2 pt-1", children: [
|
|
85
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Burdenoff ecosystem" }),
|
|
86
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
Search,
|
|
89
|
+
{
|
|
90
|
+
className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground",
|
|
91
|
+
"aria-hidden": "true"
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsx(
|
|
95
|
+
Input,
|
|
96
|
+
{
|
|
97
|
+
type: "search",
|
|
98
|
+
value: query,
|
|
99
|
+
onChange: (e) => setQuery(e.target.value),
|
|
100
|
+
placeholder: searchPlaceholder,
|
|
101
|
+
className: "h-8 pl-8 text-sm",
|
|
102
|
+
"aria-label": searchPlaceholder,
|
|
103
|
+
onKeyDown: (e) => {
|
|
104
|
+
if (e.key === "Escape") {
|
|
105
|
+
setQuery("");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
] })
|
|
111
|
+
] }),
|
|
112
|
+
/* @__PURE__ */ jsx(DropdownMenu.Separator, { className: "my-1 h-px bg-border/60" }),
|
|
113
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-[min(60vh,24rem)] overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: emptyText }) : filtered.map((product) => /* @__PURE__ */ jsx(DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
114
|
+
"a",
|
|
115
|
+
{
|
|
116
|
+
href: product.websiteUrl,
|
|
117
|
+
target: "_blank",
|
|
118
|
+
rel: "noopener noreferrer",
|
|
119
|
+
className: cn(
|
|
120
|
+
"flex items-center gap-3 rounded-md px-2 py-2 text-sm outline-none",
|
|
121
|
+
"text-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
|
|
122
|
+
),
|
|
123
|
+
children: [
|
|
124
|
+
product.logoUrl ? /* @__PURE__ */ jsx(
|
|
125
|
+
"img",
|
|
126
|
+
{
|
|
127
|
+
src: product.logoUrl,
|
|
128
|
+
alt: "",
|
|
129
|
+
"aria-hidden": "true",
|
|
130
|
+
className: "h-5 w-5 shrink-0 rounded object-contain"
|
|
131
|
+
}
|
|
132
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded bg-primary/10 text-[10px] font-bold text-primary", children: product.name.charAt(0) }),
|
|
133
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: product.name })
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
) }, product.slug)) }),
|
|
137
|
+
/* @__PURE__ */ jsx(DropdownMenu.Arrow, { className: "fill-popover" })
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
) })
|
|
141
|
+
] });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export { WebsiteSwitcher };
|
|
145
|
+
//# sourceMappingURL=website-switcher.mjs.map
|
|
146
|
+
//# sourceMappingURL=website-switcher.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/ui/input.tsx","../../src/components/website-switcher.tsx"],"names":["jsx"],"mappings":"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","file":"website-switcher.mjs","sourcesContent":["/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nconst Input = React.forwardRef<HTMLInputElement, React.ComponentProps<\"input\">>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n","\"use client\";\n\n/**\n * WebsiteSwitcher Component\n *\n * A dropdown menu for navigating between Burdenoff ecosystem product websites.\n * Includes a search filter and renders each product with its logo and name.\n *\n * @example\n * ```tsx\n * import { WebsiteSwitcher } from '@burdenoff/website-sdk'\n *\n * <WebsiteSwitcher\n * products={[\n * { slug: 'vibecontrols', name: 'VibeControls', logoUrl: '/vibe.svg', websiteUrl: 'https://vibecontrols.com' },\n * { slug: 'fluidgrids', name: 'FluidGrids', logoUrl: '/fg.svg', websiteUrl: 'https://fluidgrids.com' },\n * ]}\n * />\n * ```\n */\n\nimport { useMemo, useState } from \"react\";\n\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { ChevronDown, Globe, Search } from \"lucide-react\";\n\nimport { Input } from \"../ui/input\";\nimport { cn } from \"../utils/cn\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WebsiteSwitcherProduct {\n /** Stable identifier for the product. */\n slug: string;\n /** Human-readable product name. */\n name: string;\n /** URL to the product logo (absolute or relative). */\n logoUrl?: string | null;\n /** Product marketing site URL. */\n websiteUrl: string;\n}\n\nexport interface WebsiteSwitcherProps {\n /** All Burdenoff ecosystem products to display. */\n products: WebsiteSwitcherProduct[];\n /** Accessible label for the trigger. */\n triggerLabel?: string;\n /** Placeholder text for the search input. */\n searchPlaceholder?: string;\n /** Empty-state text when filtering returns no results. */\n emptyText?: string;\n /** Optional additional CSS class for the trigger. */\n className?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeSearch(value: string): string {\n return value.toLowerCase().trim();\n}\n\nfunction filterProducts(\n products: WebsiteSwitcherProduct[],\n query: string,\n): WebsiteSwitcherProduct[] {\n const normalized = normalizeSearch(query);\n if (!normalized) return products;\n return products.filter((p) => normalizeSearch(p.name).includes(normalized));\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function WebsiteSwitcher({\n products,\n triggerLabel = \"Explore products\",\n searchPlaceholder = \"Find a product…\",\n emptyText = \"No products match your search.\",\n className,\n}: WebsiteSwitcherProps) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n\n const filtered = useMemo(\n () => filterProducts(products, query),\n [products, query],\n );\n\n return (\n <DropdownMenu.Root open={open} onOpenChange={setOpen}>\n <DropdownMenu.Trigger\n className={cn(\n \"inline-flex items-center gap-1.5 text-sm font-medium transition-colors\",\n \"text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded-md\",\n className,\n )}\n aria-label={triggerLabel}\n >\n <Globe className=\"h-4 w-4\" aria-hidden=\"true\" />\n <span className=\"hidden sm:inline\">{triggerLabel}</span>\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n aria-hidden=\"true\"\n />\n </DropdownMenu.Trigger>\n\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className=\"z-50 min-w-[16rem] max-w-[20rem] rounded-lg border border-border/60 bg-popover p-2 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2\"\n sideOffset={8}\n align=\"end\"\n avoidCollisions\n >\n <div className=\"px-2 pb-2 pt-1\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Burdenoff ecosystem\n </p>\n <div className=\"relative\">\n <Search\n className=\"absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <Input\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={searchPlaceholder}\n className=\"h-8 pl-8 text-sm\"\n aria-label={searchPlaceholder}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n setQuery(\"\");\n }\n }}\n />\n </div>\n </div>\n\n <DropdownMenu.Separator className=\"my-1 h-px bg-border/60\" />\n\n <div className=\"max-h-[min(60vh,24rem)] overflow-y-auto py-1\">\n {filtered.length === 0 ? (\n <div className=\"px-3 py-4 text-center text-sm text-muted-foreground\">\n {emptyText}\n </div>\n ) : (\n filtered.map((product) => (\n <DropdownMenu.Item key={product.slug} asChild>\n <a\n href={product.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n \"flex items-center gap-3 rounded-md px-2 py-2 text-sm outline-none\",\n \"text-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\",\n )}\n >\n {product.logoUrl ? (\n <img\n src={product.logoUrl}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 rounded object-contain\"\n />\n ) : (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded bg-primary/10 text-[10px] font-bold text-primary\">\n {product.name.charAt(0)}\n </span>\n )}\n <span className=\"truncate\">{product.name}</span>\n </a>\n </DropdownMenu.Item>\n ))\n )}\n </div>\n\n <DropdownMenu.Arrow className=\"fill-popover\" />\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n}\n"]}
|
package/dist/content/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
2
3
|
|
|
3
4
|
interface ContentPageData {
|
|
4
5
|
id: string;
|
|
@@ -134,6 +135,20 @@ interface CaseStudyPageProps {
|
|
|
134
135
|
declare function CaseStudiesListPage(props: CaseStudiesListPageProps): react_jsx_runtime.JSX.Element;
|
|
135
136
|
declare function CaseStudyPage(props: CaseStudyPageProps): react_jsx_runtime.JSX.Element;
|
|
136
137
|
|
|
138
|
+
interface ChangelogEntry {
|
|
139
|
+
/** Release date as an ISO string. */
|
|
140
|
+
date: string;
|
|
141
|
+
/** Version identifier, e.g. "1.2.0". */
|
|
142
|
+
version: string;
|
|
143
|
+
/** Entry headline. */
|
|
144
|
+
title: string;
|
|
145
|
+
/** Category used for filtering, e.g. "feature", "fix", "improvement". */
|
|
146
|
+
category: string;
|
|
147
|
+
/** Entry body — plain text, markdown, or a React node. */
|
|
148
|
+
content: ReactNode | string;
|
|
149
|
+
/** Optional tags for search and filtering. */
|
|
150
|
+
tags?: string[];
|
|
151
|
+
}
|
|
137
152
|
interface ChangelogPageProps {
|
|
138
153
|
productName?: string;
|
|
139
154
|
heroEyebrow?: string;
|
|
@@ -148,6 +163,14 @@ interface ChangelogPageProps {
|
|
|
148
163
|
seoTitle?: string;
|
|
149
164
|
seoDescription?: string;
|
|
150
165
|
seoKeywords?: string;
|
|
166
|
+
/**
|
|
167
|
+
* Optional prop-driven entries. When provided, the component skips the CMS
|
|
168
|
+
* fetch and renders these entries with search, category filters, and
|
|
169
|
+
* pagination.
|
|
170
|
+
*/
|
|
171
|
+
entries?: ChangelogEntry[];
|
|
172
|
+
/** Number of entries per page in prop-driven mode. Defaults to 10. */
|
|
173
|
+
pageSize?: number;
|
|
151
174
|
}
|
|
152
175
|
declare function ChangelogPage(props: ChangelogPageProps): react_jsx_runtime.JSX.Element;
|
|
153
176
|
|
|
@@ -221,4 +244,4 @@ interface ContractsPageProps {
|
|
|
221
244
|
}
|
|
222
245
|
declare function ContractsPage(props: ContractsPageProps): react_jsx_runtime.JSX.Element;
|
|
223
246
|
|
|
224
|
-
export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
|
|
247
|
+
export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, type ChangelogEntry, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
|
package/dist/content/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
2
3
|
|
|
3
4
|
interface ContentPageData {
|
|
4
5
|
id: string;
|
|
@@ -134,6 +135,20 @@ interface CaseStudyPageProps {
|
|
|
134
135
|
declare function CaseStudiesListPage(props: CaseStudiesListPageProps): react_jsx_runtime.JSX.Element;
|
|
135
136
|
declare function CaseStudyPage(props: CaseStudyPageProps): react_jsx_runtime.JSX.Element;
|
|
136
137
|
|
|
138
|
+
interface ChangelogEntry {
|
|
139
|
+
/** Release date as an ISO string. */
|
|
140
|
+
date: string;
|
|
141
|
+
/** Version identifier, e.g. "1.2.0". */
|
|
142
|
+
version: string;
|
|
143
|
+
/** Entry headline. */
|
|
144
|
+
title: string;
|
|
145
|
+
/** Category used for filtering, e.g. "feature", "fix", "improvement". */
|
|
146
|
+
category: string;
|
|
147
|
+
/** Entry body — plain text, markdown, or a React node. */
|
|
148
|
+
content: ReactNode | string;
|
|
149
|
+
/** Optional tags for search and filtering. */
|
|
150
|
+
tags?: string[];
|
|
151
|
+
}
|
|
137
152
|
interface ChangelogPageProps {
|
|
138
153
|
productName?: string;
|
|
139
154
|
heroEyebrow?: string;
|
|
@@ -148,6 +163,14 @@ interface ChangelogPageProps {
|
|
|
148
163
|
seoTitle?: string;
|
|
149
164
|
seoDescription?: string;
|
|
150
165
|
seoKeywords?: string;
|
|
166
|
+
/**
|
|
167
|
+
* Optional prop-driven entries. When provided, the component skips the CMS
|
|
168
|
+
* fetch and renders these entries with search, category filters, and
|
|
169
|
+
* pagination.
|
|
170
|
+
*/
|
|
171
|
+
entries?: ChangelogEntry[];
|
|
172
|
+
/** Number of entries per page in prop-driven mode. Defaults to 10. */
|
|
173
|
+
pageSize?: number;
|
|
151
174
|
}
|
|
152
175
|
declare function ChangelogPage(props: ChangelogPageProps): react_jsx_runtime.JSX.Element;
|
|
153
176
|
|
|
@@ -221,4 +244,4 @@ interface ContractsPageProps {
|
|
|
221
244
|
}
|
|
222
245
|
declare function ContractsPage(props: ContractsPageProps): react_jsx_runtime.JSX.Element;
|
|
223
246
|
|
|
224
|
-
export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
|
|
247
|
+
export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, type ChangelogEntry, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
|