@vadimcomanescu/nadicode-design-system 5.0.1 → 6.0.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.
Files changed (66) hide show
  1. package/.agents/skills/seed/SKILL.md +39 -17
  2. package/.agents/skills/seed/references/composition.md +38 -22
  3. package/.agents/skills/seed/references/glass-and-effects.md +7 -5
  4. package/.agents/skills/seed/references/responsive.md +22 -63
  5. package/.agents/skills/seed/references/state-machines.md +54 -46
  6. package/contracts/release-governance-baseline.json +2 -2
  7. package/dist/{TeamPage-IYWL6N4I.js → TeamPage-OXOXATQO.js} +22 -20
  8. package/dist/catalog/catalog.d.ts +67 -1
  9. package/dist/catalog/catalog.js +8 -8
  10. package/dist/catalog/components.d.ts +4 -2
  11. package/dist/catalog/components.js +17 -16
  12. package/dist/catalog/definitions/blocks-content.d.ts +10 -0
  13. package/dist/catalog/definitions/blocks-content.js +1 -1
  14. package/dist/catalog/definitions/blocks-crud.d.ts +53 -1
  15. package/dist/catalog/definitions/blocks-crud.js +1 -1
  16. package/dist/catalog/definitions/blocks-data.d.ts +4 -0
  17. package/dist/catalog/definitions/blocks-data.js +1 -1
  18. package/dist/catalog/definitions/index.d.ts +67 -1
  19. package/dist/catalog/definitions/index.js +7 -7
  20. package/dist/catalog/primitives/index.js +3 -3
  21. package/dist/{chunk-4ZST7OY5.js → chunk-5DLTCQN4.js} +29 -7
  22. package/dist/{chunk-CTVV6JS6.js → chunk-6PEJEOX4.js} +1 -1
  23. package/dist/chunk-ACIJEUAH.js +213 -0
  24. package/dist/{chunk-PQBVNNEG.js → chunk-DEILZQEX.js} +12 -3
  25. package/dist/{chunk-VQVWFCHF.js → chunk-HXKCPTY3.js} +6 -6
  26. package/dist/{chunk-A4QNTJUR.js → chunk-J3CSDFH7.js} +6 -2
  27. package/dist/{chunk-XX4XJJSH.js → chunk-JZERLGVV.js} +1 -1
  28. package/dist/{chunk-NBDUZA66.js → chunk-KOJ3X2F3.js} +3 -1
  29. package/dist/{chunk-XMGWLDNG.js → chunk-KSJUX6EA.js} +2 -2
  30. package/dist/{chunk-JDHD4L6N.js → chunk-KUL5OOXZ.js} +1 -1
  31. package/dist/{chunk-AP5SGSN7.js → chunk-P3CGISJM.js} +4 -0
  32. package/dist/{chunk-IW36SVOH.js → chunk-PPVSKK77.js} +41 -3
  33. package/dist/{chunk-D6MFOI3N.js → chunk-QMDQVJ4P.js} +12 -5
  34. package/dist/{chunk-UPMSE6PQ.js → chunk-TCDBSHAY.js} +4 -2
  35. package/dist/{chunk-PJ7DVYWA.js → chunk-TOMUOPVE.js} +4 -0
  36. package/dist/{chunk-5RBO2IMZ.js → chunk-WJ7TDY4S.js} +5 -1
  37. package/dist/{chunk-PIFVLS5S.js → chunk-X5MMPEIL.js} +15 -13
  38. package/dist/{chunk-3LROWCZE.js → chunk-XNTU2I2Y.js} +11 -3
  39. package/dist/components/blocks/ApiKeysBlock.js +1 -1
  40. package/dist/components/blocks/BlogIndexBlock.d.ts +1 -1
  41. package/dist/components/blocks/BlogIndexBlock.js +1 -1
  42. package/dist/components/blocks/CommandPaletteBlock.js +1 -1
  43. package/dist/components/blocks/CrudListBlock.js +1 -1
  44. package/dist/components/blocks/DashboardBlock.js +1 -1
  45. package/dist/components/blocks/DataGridBlock.d.ts +1 -1
  46. package/dist/components/blocks/DataGridBlock.js +1 -1
  47. package/dist/components/blocks/IntegrationsBlock.js +2 -2
  48. package/dist/components/blocks/PricingBlock.d.ts +3 -1
  49. package/dist/components/blocks/PricingBlock.js +1 -1
  50. package/dist/components/blocks/SettingsNavBlock.d.ts +1 -1
  51. package/dist/components/blocks/SettingsNavBlock.js +1 -1
  52. package/dist/components/blocks/TeamManagementBlock.d.ts +3 -0
  53. package/dist/components/blocks/TeamManagementBlock.js +129 -0
  54. package/dist/components/blocks/TeamShowcaseBlock.d.ts +3 -0
  55. package/dist/components/blocks/{TeamBlock.js → TeamShowcaseBlock.js} +1 -1
  56. package/dist/components/logos/index.js +1 -1
  57. package/dist/lib/json-render/app.js +1 -1
  58. package/dist/lib/json-render/catalog.d.ts +8 -0
  59. package/dist/lib/json-render/catalog.js +9 -9
  60. package/dist/lib/json-render/registry.js +9 -9
  61. package/dist/lib/json-render/showcase-spec.js +1 -1
  62. package/eslint-rules/nadicode/data/catalog-names.json +2 -1
  63. package/package.json +1 -1
  64. package/dist/components/blocks/TeamBlock.d.ts +0 -3
  65. package/dist/{chunk-PQOL3E2V.js → chunk-3KEBY2I3.js} +2 -2
  66. package/dist/{chunk-IYK2ABFE.js → chunk-FUROL3RA.js} +1 -1
@@ -1,16 +1,16 @@
1
- export { primitiveComponents } from '../../chunk-PQOL3E2V.js';
1
+ export { primitiveComponents } from '../../chunk-3KEBY2I3.js';
2
+ import '../../chunk-5B3GLRX3.js';
2
3
  import '../../chunk-YGDO5KDY.js';
4
+ import '../../chunk-YMAEXGD2.js';
3
5
  import '../../chunk-EJQ73FJ5.js';
4
6
  import '../../chunk-4GLBFZVI.js';
5
7
  import '../../chunk-P5I63ETD.js';
6
8
  import '../../chunk-OUXJUUCB.js';
7
9
  import '../../chunk-XYMFKNKG.js';
8
10
  import '../../chunk-3QMHVXSQ.js';
9
- import '../../chunk-5B3GLRX3.js';
10
11
  import '../../chunk-GXUQFXT7.js';
11
12
  import '../../chunk-65CUE2WL.js';
12
13
  import '../../chunk-L55GVKLY.js';
13
- import '../../chunk-YMAEXGD2.js';
14
14
  import '../../chunk-2NMP3J5R.js';
15
15
  import '../../chunk-ANBJ2OLC.js';
16
16
  import '../../chunk-LV4LBWCS.js';
@@ -3,19 +3,24 @@ import { Card, CardHeader, CardTitle, CardContent } from './chunk-7UY24UWL.js';
3
3
  import { Button } from './chunk-7KIDDF3I.js';
4
4
  import { Badge } from './chunk-S4JAHKOP.js';
5
5
  import { cn } from './chunk-QYZT24TS.js';
6
+ import { useBoundProp } from '@json-render/react';
6
7
  import { jsxs, jsx } from 'react/jsx-runtime';
7
8
 
8
9
  var EMPTY_CATEGORIES = [];
9
10
  var EMPTY_ARTICLES = [];
10
11
  function BlogIndexBlock({
11
12
  props,
12
- emit
13
+ emit,
14
+ bindings
13
15
  }) {
14
16
  const categories = props.categories ?? EMPTY_CATEGORIES;
15
17
  const articles = props.articles ?? EMPTY_ARTICLES;
16
- const activeCategoryId = props.activeCategoryId ?? null;
17
18
  const pagination = props.pagination;
18
19
  const state = props.state ?? "has-data";
20
+ const [, setBoundActiveCategoryId] = useBoundProp(props.activeCategoryId, bindings?.activeCategoryId);
21
+ const [, setBoundSelectedArticleId] = useBoundProp(props.selectedArticleId, bindings?.selectedArticleId);
22
+ const [, setBoundCurrentPage] = useBoundProp(props.currentPage, bindings?.currentPage);
23
+ const activeCategoryId = props.activeCategoryId ?? null;
19
24
  const emptyTitle = props.emptyTitle ?? "No content available";
20
25
  const emptyDescription = props.emptyDescription ?? "Check back later for new articles.";
21
26
  const className = props.className;
@@ -42,7 +47,10 @@ function BlogIndexBlock({
42
47
  type: "button",
43
48
  variant: activeCategoryId === null ? "primary" : "outline",
44
49
  size: "sm",
45
- onClick: () => emit("categoryChange"),
50
+ onClick: () => {
51
+ setBoundActiveCategoryId(null);
52
+ emit("categoryChange");
53
+ },
46
54
  children: "All"
47
55
  }
48
56
  ),
@@ -52,7 +60,10 @@ function BlogIndexBlock({
52
60
  type: "button",
53
61
  variant: activeCategoryId === category.id ? "primary" : "outline",
54
62
  size: "sm",
55
- onClick: () => emit("categoryChange"),
63
+ onClick: () => {
64
+ setBoundActiveCategoryId(category.id);
65
+ emit("categoryChange");
66
+ },
56
67
  children: [
57
68
  category.label,
58
69
  typeof category.count === "number" ? ` (${category.count})` : ""
@@ -109,7 +120,10 @@ function BlogIndexBlock({
109
120
  type: "button",
110
121
  variant: "outline",
111
122
  size: "sm",
112
- onClick: () => emit("articleOpen"),
123
+ onClick: () => {
124
+ setBoundSelectedArticleId(article.id);
125
+ emit("articleOpen");
126
+ },
113
127
  children: "Open"
114
128
  }
115
129
  )
@@ -130,7 +144,11 @@ function BlogIndexBlock({
130
144
  variant: "outline",
131
145
  size: "sm",
132
146
  disabled: pagination.page <= 1,
133
- onClick: () => emit("pageChange"),
147
+ onClick: () => {
148
+ const target = pagination.page - 1;
149
+ setBoundCurrentPage(target);
150
+ emit("pageChange");
151
+ },
134
152
  children: "Previous page"
135
153
  }
136
154
  ),
@@ -141,7 +159,11 @@ function BlogIndexBlock({
141
159
  variant: "outline",
142
160
  size: "sm",
143
161
  disabled: pagination.page >= pagination.totalPages,
144
- onClick: () => emit("pageChange"),
162
+ onClick: () => {
163
+ const target = pagination.page + 1;
164
+ setBoundCurrentPage(target);
165
+ emit("pageChange");
166
+ },
145
167
  children: "Next page"
146
168
  }
147
169
  )
@@ -1,4 +1,4 @@
1
- import { allDefinitions } from './chunk-VQVWFCHF.js';
1
+ import { allDefinitions } from './chunk-HXKCPTY3.js';
2
2
 
3
3
  // src/catalog/catalog.ts
4
4
  var seedComponentDefinitions = allDefinitions;
@@ -0,0 +1,213 @@
1
+ import { Typography } from './chunk-Q7PCHHVJ.js';
2
+ import { RoleBadge } from './chunk-OHCQPI3W.js';
3
+ import { Heading } from './chunk-UXX6HHPS.js';
4
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuItem } from './chunk-ETS5O4ZQ.js';
5
+ import { Input } from './chunk-AP3XXYAY.js';
6
+ import { Empty, EmptyTitle, EmptyDescription } from './chunk-4TF4QFIM.js';
7
+ import { Skeleton } from './chunk-RASEB2XI.js';
8
+ import { Avatar, AvatarImage, AvatarFallback } from './chunk-NAAU5IWU.js';
9
+ import { Button } from './chunk-7KIDDF3I.js';
10
+ import { UsersIcon } from './chunk-WUO7OONN.js';
11
+ import { PlusIcon } from './chunk-E7RBK6ML.js';
12
+ import { SearchIcon } from './chunk-T6BRD7TS.js';
13
+ import { EllipsisIcon } from './chunk-5ESF6N36.js';
14
+ import { Badge } from './chunk-S4JAHKOP.js';
15
+ import { cn } from './chunk-QYZT24TS.js';
16
+ import { useBoundProp } from '@json-render/react';
17
+ import { useState, useMemo } from 'react';
18
+ import { jsxs, jsx } from 'react/jsx-runtime';
19
+
20
+ var ROLES = ["owner", "admin", "member", "guest"];
21
+ var DEFAULT_MEMBERS = [
22
+ { id: "dm-1", name: "Sofia Reyes", email: "sofia@acme.com", role: "owner", avatar: null, joinedAt: "2025-06-01T00:00:00Z", status: "active" },
23
+ { id: "dm-2", name: "Marcus Chen", email: "marcus@acme.com", role: "admin", avatar: null, joinedAt: "2025-08-15T00:00:00Z", status: "active" },
24
+ { id: "dm-3", name: "Aisha Patel", email: "aisha@acme.com", role: "member", avatar: null, joinedAt: "2025-11-20T00:00:00Z", status: "active" },
25
+ { id: "dm-4", name: "Jordan Lee", email: "jordan@acme.com", role: "guest", avatar: null, joinedAt: null, status: "pending" }
26
+ ];
27
+ function deriveState(state, members) {
28
+ if (state) return state;
29
+ if (members.length === 0) return "empty";
30
+ return "has-data";
31
+ }
32
+ function getInitials(name) {
33
+ return name.split(" ").map((part) => part[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
34
+ }
35
+ var STATUS_LABELS = {
36
+ active: "Active",
37
+ pending: "Pending",
38
+ deactivated: "Deactivated"
39
+ };
40
+ function StatusBadge({ status }) {
41
+ if (!status || status === "active") return null;
42
+ return /* @__PURE__ */ jsx(
43
+ Badge,
44
+ {
45
+ variant: "outline",
46
+ className: cn(
47
+ status === "pending" && "border-warning/40 text-warning",
48
+ status === "deactivated" && "border-destructive/40 text-destructive/80"
49
+ ),
50
+ children: STATUS_LABELS[status] ?? status
51
+ }
52
+ );
53
+ }
54
+ function TeamManagementBlock({
55
+ props,
56
+ emit,
57
+ bindings
58
+ }) {
59
+ const members = props.members ?? DEFAULT_MEMBERS;
60
+ const title = props.title ?? "Team Members";
61
+ const description = props.description;
62
+ const errorMessage = props.errorMessage;
63
+ const className = props.className;
64
+ const [, setBoundSearchQuery] = useBoundProp(
65
+ props.searchQuery,
66
+ bindings?.searchQuery
67
+ );
68
+ const [localSearchQuery, setLocalSearchQuery] = useState("");
69
+ const isBoundSearch = !!bindings?.searchQuery;
70
+ const searchQuery = isBoundSearch ? props.searchQuery ?? "" : localSearchQuery;
71
+ const setSearchQuery = isBoundSearch ? setBoundSearchQuery : setLocalSearchQuery;
72
+ const [, setBoundSelectedMemberId] = useBoundProp(
73
+ props.selectedMemberId,
74
+ bindings?.selectedMemberId
75
+ );
76
+ const [, setBoundSelectedRole] = useBoundProp(
77
+ props.selectedRole,
78
+ bindings?.selectedRole
79
+ );
80
+ const resolvedState = deriveState(props.state, members);
81
+ const filteredMembers = useMemo(() => {
82
+ if (!searchQuery.trim()) return members;
83
+ const q = searchQuery.toLowerCase();
84
+ return members.filter(
85
+ (m) => m.name.toLowerCase().includes(q) || m.email.toLowerCase().includes(q) || m.role.toLowerCase().includes(q)
86
+ );
87
+ }, [members, searchQuery]);
88
+ return /* @__PURE__ */ jsxs("section", { className: cn("space-y-6", className), children: [
89
+ /* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between", children: [
90
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
91
+ /* @__PURE__ */ jsx(Heading, { level: 3, children: title }),
92
+ description ? /* @__PURE__ */ jsx(Typography, { variant: "muted", children: description }) : null
93
+ ] }),
94
+ /* @__PURE__ */ jsxs(
95
+ Button,
96
+ {
97
+ onClick: () => emit("invite"),
98
+ "aria-label": "Invite member",
99
+ children: [
100
+ /* @__PURE__ */ jsx(PlusIcon, { size: 16, className: "mr-2" }),
101
+ "Invite"
102
+ ]
103
+ }
104
+ )
105
+ ] }),
106
+ resolvedState !== "loading" && resolvedState !== "error" && members.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
107
+ /* @__PURE__ */ jsx(SearchIcon, { size: 16, className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary" }),
108
+ /* @__PURE__ */ jsx(
109
+ Input,
110
+ {
111
+ "aria-label": "Search members",
112
+ placeholder: "Search by name, email, or role...",
113
+ value: searchQuery,
114
+ className: "pl-9",
115
+ onChange: (e) => {
116
+ setSearchQuery(e.target.value);
117
+ emit("searchChange");
118
+ }
119
+ }
120
+ )
121
+ ] }) : null,
122
+ resolvedState === "loading" ? /* @__PURE__ */ jsx("div", { className: "space-y-3", "aria-label": "Loading team members", children: Array.from({ length: 3 }, (_, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 rounded-lg border border-border p-4", children: [
123
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-10 rounded-full" }),
124
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
125
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" }),
126
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-48" })
127
+ ] }),
128
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-16" })
129
+ ] }, i)) }) : null,
130
+ resolvedState === "error" ? /* @__PURE__ */ jsx(
131
+ "div",
132
+ {
133
+ role: "alert",
134
+ className: "rounded-md border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive",
135
+ children: errorMessage ?? "Unable to load team members. Please try again."
136
+ }
137
+ ) : null,
138
+ resolvedState === "empty" || resolvedState === "has-data" && filteredMembers.length === 0 ? /* @__PURE__ */ jsxs(Empty, { children: [
139
+ /* @__PURE__ */ jsx(UsersIcon, { size: 40, className: "text-text-tertiary" }),
140
+ /* @__PURE__ */ jsx(EmptyTitle, { children: searchQuery.trim() ? "No members found" : "No team members" }),
141
+ /* @__PURE__ */ jsx(EmptyDescription, { children: searchQuery.trim() ? "Try a different search term." : "Invite your first team member to get started." })
142
+ ] }) : null,
143
+ resolvedState === "has-data" && filteredMembers.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "divide-y divide-border rounded-lg border border-border", role: "list", children: filteredMembers.map((member) => /* @__PURE__ */ jsxs(
144
+ "li",
145
+ {
146
+ className: "flex items-center gap-4 px-4 py-3",
147
+ children: [
148
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-10 w-10", children: [
149
+ member.avatar ? /* @__PURE__ */ jsx(AvatarImage, { src: member.avatar, alt: member.name }) : null,
150
+ /* @__PURE__ */ jsx(AvatarFallback, { children: getInitials(member.name) })
151
+ ] }),
152
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
153
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-medium truncate", children: member.name }),
154
+ /* @__PURE__ */ jsx(Typography, { variant: "muted", className: "truncate text-xs", children: member.email })
155
+ ] }),
156
+ /* @__PURE__ */ jsxs("div", { className: "hidden items-center gap-2 sm:flex", children: [
157
+ /* @__PURE__ */ jsx(StatusBadge, { status: member.status }),
158
+ /* @__PURE__ */ jsx(RoleBadge, { role: member.role })
159
+ ] }),
160
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
161
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
162
+ Button,
163
+ {
164
+ variant: "ghost",
165
+ size: "sm",
166
+ "aria-label": `Actions for ${member.name}`,
167
+ children: /* @__PURE__ */ jsx(EllipsisIcon, { size: 16 })
168
+ }
169
+ ) }),
170
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
171
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Actions" }),
172
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
173
+ /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
174
+ /* @__PURE__ */ jsx(DropdownMenuSubTrigger, { children: "Change role" }),
175
+ /* @__PURE__ */ jsx(DropdownMenuSubContent, { children: ROLES.map((role) => /* @__PURE__ */ jsxs(
176
+ DropdownMenuItem,
177
+ {
178
+ disabled: role === member.role,
179
+ onClick: () => {
180
+ setBoundSelectedMemberId(member.id);
181
+ setBoundSelectedRole(role);
182
+ emit("roleChange");
183
+ },
184
+ children: [
185
+ role.charAt(0).toUpperCase() + role.slice(1),
186
+ role === member.role ? " (current)" : ""
187
+ ]
188
+ },
189
+ role
190
+ )) })
191
+ ] }),
192
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
193
+ /* @__PURE__ */ jsx(
194
+ DropdownMenuItem,
195
+ {
196
+ className: "text-destructive focus:text-destructive",
197
+ onClick: () => {
198
+ setBoundSelectedMemberId(member.id);
199
+ emit("removeMember");
200
+ },
201
+ children: "Remove member"
202
+ }
203
+ )
204
+ ] })
205
+ ] })
206
+ ]
207
+ },
208
+ member.id
209
+ )) }) : null
210
+ ] });
211
+ }
212
+
213
+ export { TeamManagementBlock };
@@ -9,6 +9,7 @@ import { CheckIcon } from './chunk-CXACRCZ4.js';
9
9
  import { Badge } from './chunk-S4JAHKOP.js';
10
10
  import { cn } from './chunk-QYZT24TS.js';
11
11
  import { useTranslations } from 'next-intl';
12
+ import { useBoundProp } from '@json-render/react';
12
13
  import { useState } from 'react';
13
14
  import { jsx, jsxs } from 'react/jsx-runtime';
14
15
 
@@ -47,13 +48,18 @@ var defaultPlans = [
47
48
  badge: null
48
49
  }
49
50
  ];
50
- function PricingBlock({ props, emit }) {
51
+ function PricingBlock({ props, emit, bindings }) {
51
52
  const title = props.title ?? "Simple, transparent pricing";
52
53
  const description = props.description ?? "Choose the plan that's right for you. Change or cancel anytime.";
53
54
  const plans = props.plans ?? defaultPlans;
54
55
  const showBillingToggle = props.showBillingToggle ?? true;
55
56
  const t = useTranslations("blocks.pricingBlock");
56
- const [isYearly, setIsYearly] = useState(false);
57
+ const [, setBoundSelectedPlanName] = useBoundProp(props.selectedPlanName, bindings?.selectedPlanName);
58
+ const [, setBoundIsYearly] = useBoundProp(props.isYearly, bindings?.isYearly);
59
+ const [localIsYearly, setLocalIsYearly] = useState(false);
60
+ const isYearlyBound = !!bindings?.isYearly;
61
+ const isYearly = isYearlyBound ? props.isYearly ?? false : localIsYearly;
62
+ const setIsYearly = isYearlyBound ? setBoundIsYearly : setLocalIsYearly;
57
63
  return /* @__PURE__ */ jsx("section", { className: "py-16 md:py-24", children: /* @__PURE__ */ jsxs("div", { className: "container mx-auto px-6 lg:px-8", children: [
58
64
  /* @__PURE__ */ jsxs("div", { className: "mb-12 text-center", children: [
59
65
  /* @__PURE__ */ jsx(Heading, { level: 2, size: "section", className: "mb-4 sm:text-4xl", children: title }),
@@ -97,7 +103,10 @@ function PricingBlock({ props, emit }) {
97
103
  feature
98
104
  ] }, feature)) })
99
105
  ] }),
100
- /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(Button, { className: "w-full", variant: plan.variant, onClick: () => emit("selectPlan"), children: plan.action }) })
106
+ /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(Button, { className: "w-full", variant: plan.variant, onClick: () => {
107
+ setBoundSelectedPlanName(plan.name);
108
+ emit("selectPlan");
109
+ }, children: plan.action }) })
101
110
  ]
102
111
  },
103
112
  plan.name
@@ -1,22 +1,22 @@
1
+ import { navigationDefinitions } from './chunk-QCL76CM6.js';
1
2
  import { overlayDefinitions } from './chunk-LYI5YMC6.js';
2
3
  import { textEffectsDefinitions } from './chunk-UXYLA2IV.js';
3
4
  import { textDefinitions } from './chunk-YXRIXTXW.js';
5
+ import { blocksMiscDefinitions } from './chunk-WAIZR4CR.js';
4
6
  import { chartDefinitions } from './chunk-UQB54LIA.js';
5
7
  import { chatDefinitions } from './chunk-E4KUPYHE.js';
6
8
  import { displayDefinitions } from './chunk-W4KI424V.js';
7
9
  import { effectsDefinitions } from './chunk-7SOMHO2L.js';
8
10
  import { formDefinitions } from './chunk-XI775QZZ.js';
9
11
  import { layoutDefinitions } from './chunk-P7JS4B7U.js';
10
- import { navigationDefinitions } from './chunk-QCL76CM6.js';
12
+ import { actionDefinitions } from './chunk-XLIFWBE7.js';
11
13
  import { agentDefinitions } from './chunk-5XDYCBR6.js';
12
14
  import { blocksAgentDefinitions } from './chunk-ZU7MDRCI.js';
13
15
  import { blocksAuthDefinitions } from './chunk-ZL6BPQNN.js';
14
- import { blocksContentDefinitions } from './chunk-3LROWCZE.js';
15
- import { blocksCrudDefinitions } from './chunk-IW36SVOH.js';
16
- import { blocksDataDefinitions } from './chunk-A4QNTJUR.js';
16
+ import { blocksContentDefinitions } from './chunk-XNTU2I2Y.js';
17
+ import { blocksCrudDefinitions } from './chunk-PPVSKK77.js';
18
+ import { blocksDataDefinitions } from './chunk-J3CSDFH7.js';
17
19
  import { blocksMarketingDefinitions } from './chunk-YEAJLVGB.js';
18
- import { blocksMiscDefinitions } from './chunk-WAIZR4CR.js';
19
- import { actionDefinitions } from './chunk-XLIFWBE7.js';
20
20
 
21
21
  // src/catalog/definitions/index.ts
22
22
  var allDefinitions = {
@@ -131,7 +131,9 @@ var blocksDataDefinitions = {
131
131
  })
132
132
  ).nullable(),
133
133
  title: z.string().nullable(),
134
- description: z.string().nullable()
134
+ description: z.string().nullable(),
135
+ selectedRowId: z.string().nullable(),
136
+ selectedAction: z.string().nullable()
135
137
  }),
136
138
  events: ["rowAction"],
137
139
  description: "Data table with sortable columns, row selection, filtering, and pagination.",
@@ -141,7 +143,9 @@ var blocksDataDefinitions = {
141
143
  { id: "inv_002", amount: 150, status: "pending", email: "abe@contoso.com" }
142
144
  ],
143
145
  title: "Recent Payments",
144
- description: null
146
+ description: null,
147
+ selectedRowId: null,
148
+ selectedAction: null
145
149
  }
146
150
  },
147
151
  HeatmapChartBlock: {
@@ -25,7 +25,7 @@ import dynamic from 'next/dynamic';
25
25
  import { jsxs, jsx } from 'react/jsx-runtime';
26
26
 
27
27
  var ProfilePage = dynamic(() => import('./ProfilePage-KJVA3ZQ5.js').then((m) => ({ default: m.ProfilePage })), { ssr: false, loading: () => null });
28
- var TeamPage = dynamic(() => import('./TeamPage-IYWL6N4I.js').then((m) => ({ default: m.TeamPage })), { ssr: false, loading: () => null });
28
+ var TeamPage = dynamic(() => import('./TeamPage-OXOXATQO.js').then((m) => ({ default: m.TeamPage })), { ssr: false, loading: () => null });
29
29
  function SettingsContent({ tab }) {
30
30
  switch (tab) {
31
31
  case "profile":
@@ -62,7 +62,7 @@ var ROUTE_TREES = {
62
62
  logoCloud: { type: "LogoCloud", props: { title: null, logos: null, className: null } },
63
63
  features: { type: "FeatureBlock", props: { variant: null, badge: null, title: null, description: null, features: null } },
64
64
  stats: { type: "StatsMarketingBlock", props: { title: null, description: null, stats: null } },
65
- pricing: { type: "PricingBlock", props: { title: null, description: null, showBillingToggle: null, plans: null }, on: { selectPlan: { action: "noop" } } },
65
+ pricing: { type: "PricingBlock", props: { title: null, description: null, showBillingToggle: null, selectedPlanName: null, isYearly: null, plans: null }, on: { selectPlan: { action: "noop" } } },
66
66
  testimonials: { type: "TestimonialsBlock", props: { title: null, description: null, testimonials: null } },
67
67
  cta: { type: "CallToActionBlock", props: { title: null, description: null, primaryAction: null, secondaryAction: null } },
68
68
  faq: { type: "FAQBlock", props: { title: null, description: null, items: null }, on: { expand: { action: "noop" } } },
@@ -81,6 +81,8 @@ var ROUTE_TREES = {
81
81
  title: null,
82
82
  description: null,
83
83
  showBillingToggle: null,
84
+ selectedPlanName: null,
85
+ isYearly: null,
84
86
  plans: null
85
87
  },
86
88
  on: { selectPlan: { action: "noop" } }
@@ -31,7 +31,7 @@ var defaultSections = [
31
31
  { heading: "Engineering", members: defaultMembers },
32
32
  { heading: "Marketing", members: defaultMembers }
33
33
  ];
34
- function TeamBlock({ props }) {
34
+ function TeamShowcaseBlock({ props }) {
35
35
  const title = props.title ?? "Our team";
36
36
  const sections = props.sections ?? defaultSections;
37
37
  return /* @__PURE__ */ jsx(ScrollFadeIn, { children: /* @__PURE__ */ jsx("section", { className: "py-12 md:py-32", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-3xl px-8 lg:px-0", children: [
@@ -47,4 +47,4 @@ function TeamBlock({ props }) {
47
47
  ] }) }) });
48
48
  }
49
49
 
50
- export { TeamBlock };
50
+ export { TeamShowcaseBlock };
@@ -1,4 +1,4 @@
1
- import { seedComponentDefinitions } from './chunk-CTVV6JS6.js';
1
+ import { seedComponentDefinitions } from './chunk-6PEJEOX4.js';
2
2
  import { defineCatalog } from '@json-render/core';
3
3
  import { schema } from '@json-render/next/server';
4
4
  import { z } from 'zod';
@@ -48,6 +48,7 @@ function CrudListBlock({
48
48
  const errorMessage = props.errorMessage ?? null;
49
49
  const emptyTitle = props.emptyTitle ?? "No rows to display";
50
50
  const emptyDescription = props.emptyDescription ?? "Create a new entry or adjust filters.";
51
+ const [, setBoundCurrentPage] = useBoundProp(props.currentPage, bindings?.currentPage);
51
52
  const className = props.className;
52
53
  const resolvedState = deriveState(props.state, rows, selectedRowId);
53
54
  const pages = useMemo(() => {
@@ -141,6 +142,7 @@ function CrudListBlock({
141
142
  onClick: (event) => {
142
143
  event.preventDefault();
143
144
  if (pagination.page > 1) {
145
+ setBoundCurrentPage(pagination.page - 1);
144
146
  emit("pageChange");
145
147
  }
146
148
  },
@@ -155,6 +157,7 @@ function CrudListBlock({
155
157
  isActive: page === pagination.page,
156
158
  onClick: (event) => {
157
159
  event.preventDefault();
160
+ setBoundCurrentPage(page);
158
161
  emit("pageChange");
159
162
  },
160
163
  children: page
@@ -167,6 +170,7 @@ function CrudListBlock({
167
170
  onClick: (event) => {
168
171
  event.preventDefault();
169
172
  if (pagination.page < pagination.totalPages) {
173
+ setBoundCurrentPage(pagination.page + 1);
170
174
  emit("pageChange");
171
175
  }
172
176
  },
@@ -16,7 +16,8 @@ var blocksCrudDefinitions = {
16
16
  ).nullable(),
17
17
  title: z.string().nullable(),
18
18
  description: z.string().nullable(),
19
- newKeyName: z.string().nullable()
19
+ newKeyName: z.string().nullable(),
20
+ revokedKeyId: z.string().nullable()
20
21
  }),
21
22
  events: ["create", "revoke"],
22
23
  description: "API key management block with table display, create dialog, copy-once flow, and revoke functionality.",
@@ -27,7 +28,8 @@ var blocksCrudDefinitions = {
27
28
  ],
28
29
  title: "API Keys",
29
30
  description: "Manage your API keys for programmatic access.",
30
- newKeyName: null
31
+ newKeyName: null,
32
+ revokedKeyId: null
31
33
  }
32
34
  },
33
35
  CreateBlock: {
@@ -67,6 +69,7 @@ var blocksCrudDefinitions = {
67
69
  ).nullable(),
68
70
  filterValue: z.string().nullable(),
69
71
  pagination: z.object({ page: z.number(), totalPages: z.number() }),
72
+ currentPage: z.number().nullable(),
70
73
  errorMessage: z.string().nullable(),
71
74
  emptyTitle: z.string().nullable(),
72
75
  emptyDescription: z.string().nullable(),
@@ -92,6 +95,7 @@ var blocksCrudDefinitions = {
92
95
  filterControls: null,
93
96
  filterValue: null,
94
97
  pagination: { page: 1, totalPages: 4 },
98
+ currentPage: null,
95
99
  errorMessage: null,
96
100
  emptyTitle: null,
97
101
  emptyDescription: null,
@@ -345,7 +349,41 @@ var blocksCrudDefinitions = {
345
349
  className: null
346
350
  }
347
351
  },
348
- TeamBlock: {
352
+ TeamManagementBlock: {
353
+ props: z.object({
354
+ members: z.array(z.object({
355
+ id: z.string(),
356
+ name: z.string(),
357
+ email: z.string(),
358
+ role: z.enum(["owner", "admin", "member", "guest"]),
359
+ avatar: z.string().nullable(),
360
+ joinedAt: z.string().nullable(),
361
+ status: z.enum(["active", "pending", "deactivated"]).nullable()
362
+ })).nullable(),
363
+ searchQuery: z.string().nullable(),
364
+ selectedMemberId: z.string().nullable(),
365
+ selectedRole: z.string().nullable(),
366
+ state: z.enum(["loading", "empty", "has-data", "error"]).nullable(),
367
+ title: z.string().nullable(),
368
+ description: z.string().nullable(),
369
+ errorMessage: z.string().nullable(),
370
+ className: z.string().nullable()
371
+ }),
372
+ events: ["invite", "roleChange", "removeMember", "searchChange"],
373
+ description: "Team member management with search, role assignment, invite, and member removal.",
374
+ example: {
375
+ members: null,
376
+ searchQuery: null,
377
+ selectedMemberId: null,
378
+ selectedRole: null,
379
+ state: null,
380
+ title: null,
381
+ description: null,
382
+ errorMessage: null,
383
+ className: null
384
+ }
385
+ },
386
+ TeamShowcaseBlock: {
349
387
  props: z.object({
350
388
  title: z.string().nullable(),
351
389
  sections: z.array(
@@ -7,6 +7,7 @@ import { EllipsisIcon } from './chunk-5ESF6N36.js';
7
7
  import { Badge } from './chunk-S4JAHKOP.js';
8
8
  import { useCallback, useMemo } from 'react';
9
9
  import { useTranslations } from 'next-intl';
10
+ import { useBoundProp } from '@json-render/react';
10
11
  import { jsx, jsxs } from 'react/jsx-runtime';
11
12
 
12
13
  var USD_FORMAT = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
@@ -52,14 +53,14 @@ function createColumns(t, onRowAction) {
52
53
  {
53
54
  onClick: () => {
54
55
  navigator.clipboard.writeText(payment.id);
55
- onRowAction?.();
56
+ onRowAction?.(payment.id, "copyId");
56
57
  },
57
58
  children: t("copyPaymentId")
58
59
  }
59
60
  ),
60
61
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
61
- /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: onRowAction, children: t("viewCustomer") }),
62
- /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: onRowAction, children: t("viewPaymentDetails") })
62
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onRowAction?.(payment.id, "viewCustomer"), children: t("viewCustomer") }),
63
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onRowAction?.(payment.id, "viewDetails"), children: t("viewPaymentDetails") })
63
64
  ] })
64
65
  ] });
65
66
  }
@@ -98,12 +99,18 @@ var defaultData = [
98
99
  email: "sales@company.com"
99
100
  }
100
101
  ];
101
- function DataGridBlock({ props, emit }) {
102
+ function DataGridBlock({ props, emit, bindings }) {
102
103
  const data = props.data ?? defaultData;
103
104
  const title = props.title ?? "Recent Transactions";
104
105
  const description = props.description ?? "A sophisticated data grid with filtering and actions.";
106
+ const [, setBoundSelectedRowId] = useBoundProp(props.selectedRowId, bindings?.selectedRowId);
107
+ const [, setBoundSelectedAction] = useBoundProp(props.selectedAction, bindings?.selectedAction);
105
108
  const t = useTranslations("blocks.dataGridBlock");
106
- const onRowAction = useCallback(() => emit("rowAction"), [emit]);
109
+ const onRowAction = useCallback((rowId, action) => {
110
+ setBoundSelectedRowId(rowId);
111
+ setBoundSelectedAction(action);
112
+ emit("rowAction");
113
+ }, [emit, setBoundSelectedRowId, setBoundSelectedAction]);
107
114
  const defaultColumns = useMemo(() => createColumns(t, onRowAction), [t, onRowAction]);
108
115
  return /* @__PURE__ */ jsx(ScrollFadeIn, { children: /* @__PURE__ */ jsxs(Card, { className: "w-full", children: [
109
116
  /* @__PURE__ */ jsxs(CardHeader, { children: [
@@ -13,6 +13,7 @@ function CommandPaletteBlock({ props, bindings, emit }) {
13
13
  const placeholder = props.placeholder ?? "Search...";
14
14
  const [open, setOpen] = useState(false);
15
15
  const [boundQuery, setBoundQuery] = useBoundProp(props.searchValue, bindings?.searchValue);
16
+ const [, setBoundSelectedItemId] = useBoundProp(props.selectedItemId, bindings?.selectedItemId);
16
17
  const [localQuery, setLocalQuery] = useState("");
17
18
  const isBound = !!bindings?.searchValue;
18
19
  const query = isBound ? boundQuery ?? "" : localQuery;
@@ -30,7 +31,8 @@ function CommandPaletteBlock({ props, bindings, emit }) {
30
31
  return acc;
31
32
  }, {});
32
33
  }, [query, items]);
33
- function handleSelect(_result) {
34
+ function handleSelect(result) {
35
+ setBoundSelectedItemId(result.id);
34
36
  setOpen(false);
35
37
  setQuery("");
36
38
  emit("select");
@@ -86,7 +88,7 @@ function CommandPaletteBlock({ props, bindings, emit }) {
86
88
  CommandItem,
87
89
  {
88
90
  value: result.id,
89
- onSelect: () => handleSelect(),
91
+ onSelect: () => handleSelect(result),
90
92
  children: /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "truncate", children: result.title }) })
91
93
  },
92
94
  result.id