@omnibase/shadcn 0.4.1 → 0.4.3

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/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/components/ui/card.tsx
2
4
  import "react";
3
5
 
@@ -77,12 +79,131 @@ function CardFooter({ className, ...props }) {
77
79
  );
78
80
  }
79
81
 
82
+ // src/components/ui/messages.tsx
83
+ import * as React3 from "react";
84
+
85
+ // src/components/ui/alert.tsx
86
+ import * as React2 from "react";
87
+ import { cva } from "class-variance-authority";
88
+ import { jsx as jsx2 } from "react/jsx-runtime";
89
+ var alertVariants = cva(
90
+ "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
91
+ {
92
+ variants: {
93
+ variant: {
94
+ default: "bg-background text-foreground",
95
+ destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
96
+ warning: "border-yellow-500/50 text-yellow-700 bg-yellow-50 dark:border-yellow-500 dark:text-yellow-200 dark:bg-yellow-950/20 [&>svg]:text-yellow-600 dark:[&>svg]:text-yellow-200",
97
+ success: "border-green-500/50 text-green-700 bg-green-50 dark:border-green-500 dark:text-green-200 dark:bg-green-950/20 [&>svg]:text-green-600 dark:[&>svg]:text-green-200",
98
+ info: "border-blue-500/50 text-blue-700 bg-blue-50 dark:border-blue-500 dark:text-blue-200 dark:bg-blue-950/20 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-200"
99
+ }
100
+ },
101
+ defaultVariants: {
102
+ variant: "default"
103
+ }
104
+ }
105
+ );
106
+ var Alert = React2.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx2(
107
+ "div",
108
+ {
109
+ ref,
110
+ role: "alert",
111
+ className: cn(alertVariants({ variant }), className),
112
+ ...props
113
+ }
114
+ ));
115
+ Alert.displayName = "Alert";
116
+ var AlertTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx2(
117
+ "h5",
118
+ {
119
+ ref,
120
+ className: cn("mb-1 font-medium leading-none tracking-tight", className),
121
+ ...props
122
+ }
123
+ ));
124
+ AlertTitle.displayName = "AlertTitle";
125
+ var AlertDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx2(
126
+ "div",
127
+ {
128
+ ref,
129
+ className: cn("text-sm [&_p]:leading-relaxed", className),
130
+ ...props
131
+ }
132
+ ));
133
+ AlertDescription.displayName = "AlertDescription";
134
+
135
+ // src/components/ui/messages.tsx
136
+ import { jsx as jsx3 } from "react/jsx-runtime";
137
+ var getMessageVariant = (type) => {
138
+ switch (type) {
139
+ case "error":
140
+ return "destructive";
141
+ case "success":
142
+ return "success";
143
+ case "info":
144
+ return "info";
145
+ case "11184809":
146
+ return "warning";
147
+ default:
148
+ return "default";
149
+ }
150
+ };
151
+ var Messages = React3.forwardRef(
152
+ ({ flow, className, ...props }, ref) => {
153
+ if (!flow?.ui) return null;
154
+ const allMessages = [];
155
+ if (flow.ui.messages) {
156
+ allMessages.push(...flow.ui.messages);
157
+ }
158
+ if (flow.ui.nodes) {
159
+ flow.ui.nodes.forEach((node) => {
160
+ if (node.messages) {
161
+ allMessages.push(...node.messages);
162
+ }
163
+ });
164
+ }
165
+ if (allMessages.length === 0) return null;
166
+ return /* @__PURE__ */ jsx3(
167
+ "div",
168
+ {
169
+ ref,
170
+ className: cn("w-full max-w-md mx-auto space-y-2 mb-4", className),
171
+ ...props,
172
+ children: allMessages.map((message) => /* @__PURE__ */ jsx3(Alert, { variant: getMessageVariant(message.type), children: /* @__PURE__ */ jsx3(AlertDescription, { children: message.text }) }, message.id))
173
+ }
174
+ );
175
+ }
176
+ );
177
+ Messages.displayName = "Messages";
178
+
179
+ // src/form/types.ts
180
+ function isUiNodeInputAttributes(attributes) {
181
+ return attributes && typeof attributes === "object" && "name" in attributes && "type" in attributes;
182
+ }
183
+
184
+ // src/form/components/HiddenInput.tsx
185
+ import { jsx as jsx4 } from "react/jsx-runtime";
186
+ function HiddenInput({ node }) {
187
+ if (!isUiNodeInputAttributes(node.attributes)) {
188
+ return null;
189
+ }
190
+ return /* @__PURE__ */ jsx4(
191
+ "input",
192
+ {
193
+ name: node.attributes.name,
194
+ type: "hidden",
195
+ value: node.attributes.value || "",
196
+ readOnly: true
197
+ }
198
+ );
199
+ }
200
+
80
201
  // src/components/ui/button.tsx
81
202
  import "react";
82
203
  import { Slot } from "@radix-ui/react-slot";
83
- import { cva } from "class-variance-authority";
84
- import { jsx as jsx2 } from "react/jsx-runtime";
85
- var buttonVariants = cva(
204
+ import { cva as cva2 } from "class-variance-authority";
205
+ import { jsx as jsx5 } from "react/jsx-runtime";
206
+ var buttonVariants = cva2(
86
207
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
87
208
  {
88
209
  variants: {
@@ -115,7 +236,7 @@ function Button({
115
236
  ...props
116
237
  }) {
117
238
  const Comp = asChild ? Slot : "button";
118
- return /* @__PURE__ */ jsx2(
239
+ return /* @__PURE__ */ jsx5(
119
240
  Comp,
120
241
  {
121
242
  "data-slot": "button",
@@ -125,11 +246,78 @@ function Button({
125
246
  );
126
247
  }
127
248
 
249
+ // src/form/components/SubmitButton.tsx
250
+ import { jsx as jsx6 } from "react/jsx-runtime";
251
+ function SubmitButton({
252
+ node,
253
+ variant = "default",
254
+ className = "w-full"
255
+ }) {
256
+ if (!isUiNodeInputAttributes(node.attributes)) {
257
+ return null;
258
+ }
259
+ return /* @__PURE__ */ jsx6(
260
+ Button,
261
+ {
262
+ type: "submit",
263
+ name: node.attributes.name,
264
+ value: node.attributes.value || "",
265
+ variant,
266
+ className,
267
+ disabled: node.attributes.disabled,
268
+ children: node.meta.label?.text || node.attributes.value || "Submit"
269
+ }
270
+ );
271
+ }
272
+
273
+ // src/form/components/Divider.tsx
274
+ import { jsx as jsx7, jsxs } from "react/jsx-runtime";
275
+ function Divider({ withText = false }) {
276
+ if (withText) {
277
+ return /* @__PURE__ */ jsxs("div", { className: "relative my-6", children: [
278
+ /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx7("span", { className: "w-full border-t border-border" }) }),
279
+ /* @__PURE__ */ jsx7("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx7("span", { className: "bg-background px-3 text-muted-foreground font-medium", children: "Or continue with" }) })
280
+ ] });
281
+ }
282
+ return /* @__PURE__ */ jsx7("div", { className: "border-t border-border my-6" });
283
+ }
284
+
285
+ // src/form/components/OidcGroup.tsx
286
+ import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
287
+ function OidcGroup({
288
+ nodes,
289
+ flowAction,
290
+ flowMethod,
291
+ csrfToken,
292
+ groupIndex,
293
+ groupName
294
+ }) {
295
+ const submitButtons = nodes.filter(
296
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit"
297
+ );
298
+ return /* @__PURE__ */ jsxs2("div", { children: [
299
+ groupIndex > 0 && /* @__PURE__ */ jsx8(Divider, { withText: true }),
300
+ /* @__PURE__ */ jsx8("div", { className: "space-y-3", children: submitButtons.map((node, btnIndex) => /* @__PURE__ */ jsxs2(
301
+ "form",
302
+ {
303
+ action: flowAction,
304
+ method: flowMethod,
305
+ className: "w-full",
306
+ children: [
307
+ csrfToken && /* @__PURE__ */ jsx8(HiddenInput, { node: csrfToken }),
308
+ /* @__PURE__ */ jsx8(SubmitButton, { node, variant: "outline" })
309
+ ]
310
+ },
311
+ `${groupName}-${btnIndex}`
312
+ )) })
313
+ ] });
314
+ }
315
+
128
316
  // src/components/ui/input.tsx
129
317
  import "react";
130
- import { jsx as jsx3 } from "react/jsx-runtime";
318
+ import { jsx as jsx9 } from "react/jsx-runtime";
131
319
  function Input({ className, type, ...props }) {
132
- return /* @__PURE__ */ jsx3(
320
+ return /* @__PURE__ */ jsx9(
133
321
  "input",
134
322
  {
135
323
  type,
@@ -148,12 +336,12 @@ function Input({ className, type, ...props }) {
148
336
  // src/components/ui/label.tsx
149
337
  import "react";
150
338
  import * as LabelPrimitive from "@radix-ui/react-label";
151
- import { jsx as jsx4 } from "react/jsx-runtime";
339
+ import { jsx as jsx10 } from "react/jsx-runtime";
152
340
  function Label({
153
341
  className,
154
342
  ...props
155
343
  }) {
156
- return /* @__PURE__ */ jsx4(
344
+ return /* @__PURE__ */ jsx10(
157
345
  LabelPrimitive.Root,
158
346
  {
159
347
  "data-slot": "label",
@@ -166,109 +354,393 @@ function Label({
166
354
  );
167
355
  }
168
356
 
169
- // src/components/ui/messages.tsx
170
- import * as React6 from "react";
171
-
172
- // src/components/ui/alert.tsx
173
- import * as React5 from "react";
174
- import { cva as cva2 } from "class-variance-authority";
175
- import { jsx as jsx5 } from "react/jsx-runtime";
176
- var alertVariants = cva2(
177
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
178
- {
179
- variants: {
180
- variant: {
181
- default: "bg-background text-foreground",
182
- destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
183
- warning: "border-yellow-500/50 text-yellow-700 bg-yellow-50 dark:border-yellow-500 dark:text-yellow-200 dark:bg-yellow-950/20 [&>svg]:text-yellow-600 dark:[&>svg]:text-yellow-200",
184
- success: "border-green-500/50 text-green-700 bg-green-50 dark:border-green-500 dark:text-green-200 dark:bg-green-950/20 [&>svg]:text-green-600 dark:[&>svg]:text-green-200",
185
- info: "border-blue-500/50 text-blue-700 bg-blue-50 dark:border-blue-500 dark:text-blue-200 dark:bg-blue-950/20 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-200"
357
+ // src/form/components/FormInput.tsx
358
+ import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
359
+ function FormInput({ node }) {
360
+ if (!isUiNodeInputAttributes(node.attributes)) {
361
+ return null;
362
+ }
363
+ return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
364
+ /* @__PURE__ */ jsxs3(Label, { htmlFor: node.attributes.name, children: [
365
+ node.meta.label?.text,
366
+ node.attributes.required && /* @__PURE__ */ jsx11("span", { className: "text-destructive ml-1", children: "*" })
367
+ ] }),
368
+ /* @__PURE__ */ jsx11(
369
+ Input,
370
+ {
371
+ id: node.attributes.name,
372
+ name: node.attributes.name,
373
+ type: node.attributes.type,
374
+ defaultValue: node.attributes.value || "",
375
+ required: node.attributes.required,
376
+ disabled: node.attributes.disabled,
377
+ autoComplete: node.attributes.autocomplete,
378
+ placeholder: `Enter your ${node.meta.label?.text?.toLowerCase() || node.attributes.name}`
186
379
  }
187
- },
188
- defaultVariants: {
189
- variant: "default"
380
+ )
381
+ ] });
382
+ }
383
+
384
+ // src/form/utils.ts
385
+ var TYPE_ORDER = {
386
+ hidden: 0,
387
+ text: 1,
388
+ email: 1,
389
+ password: 1,
390
+ checkbox: 1,
391
+ submit: 2
392
+ };
393
+ function sortNodes(nodes) {
394
+ return [...nodes].sort((a, b) => {
395
+ const aIsInput = isUiNodeInputAttributes(a.attributes);
396
+ const bIsInput = isUiNodeInputAttributes(b.attributes);
397
+ if (!aIsInput && !bIsInput) return 0;
398
+ if (!aIsInput) return 1;
399
+ if (!bIsInput) return -1;
400
+ const aAttrs = a.attributes;
401
+ const bAttrs = b.attributes;
402
+ const aOrder = TYPE_ORDER[aAttrs.type] ?? 1;
403
+ const bOrder = TYPE_ORDER[bAttrs.type] ?? 1;
404
+ return aOrder - bOrder;
405
+ });
406
+ }
407
+ function findSubmitButton(nodes) {
408
+ return nodes.find(
409
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit"
410
+ );
411
+ }
412
+ function findAnchorNode(nodes) {
413
+ return nodes.find((node) => node.type === "a");
414
+ }
415
+ function filterInputNodes(nodes) {
416
+ return nodes.filter(
417
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type !== "submit" && node.attributes.type !== "hidden"
418
+ );
419
+ }
420
+ function findCsrfToken(nodes) {
421
+ return nodes.find(
422
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.name === "csrf_token"
423
+ );
424
+ }
425
+ function groupNodesByGroup(nodes) {
426
+ return nodes.reduce((groups, node) => {
427
+ const group = node.group || "default";
428
+ if (!groups[group]) {
429
+ groups[group] = [];
190
430
  }
191
- }
192
- );
193
- var Alert = React5.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx5(
194
- "div",
195
- {
196
- ref,
197
- role: "alert",
198
- className: cn(alertVariants({ variant }), className),
199
- ...props
200
- }
201
- ));
202
- Alert.displayName = "Alert";
203
- var AlertTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
204
- "h5",
205
- {
206
- ref,
207
- className: cn("mb-1 font-medium leading-none tracking-tight", className),
208
- ...props
209
- }
210
- ));
211
- AlertTitle.displayName = "AlertTitle";
212
- var AlertDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
213
- "div",
214
- {
215
- ref,
216
- className: cn("text-sm [&_p]:leading-relaxed", className),
217
- ...props
218
- }
219
- ));
220
- AlertDescription.displayName = "AlertDescription";
431
+ groups[group].push(node);
432
+ return groups;
433
+ }, {});
434
+ }
221
435
 
222
- // src/components/ui/messages.tsx
223
- import { jsx as jsx6 } from "react/jsx-runtime";
224
- var getMessageVariant = (type) => {
225
- switch (type) {
226
- case "error":
227
- return "destructive";
228
- case "success":
229
- return "success";
230
- case "info":
231
- return "info";
232
- case "11184809":
233
- return "warning";
234
- default:
235
- return "default";
436
+ // src/form/login.tsx
437
+ import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
438
+ function LoginForm({ flow, Header, register_url }) {
439
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
440
+ const csrfToken = findCsrfToken(flow.ui.nodes);
441
+ const oidcNodes = nodesByGroup.oidc || [];
442
+ const defaultNodes = nodesByGroup.default || [];
443
+ const passwordNodes = nodesByGroup.password || [];
444
+ const identifierNodes = filterInputNodes(sortNodes(defaultNodes));
445
+ const passwordInputNodes = filterInputNodes(sortNodes(passwordNodes));
446
+ const submitButton = findSubmitButton(sortNodes(passwordNodes));
447
+ const registerHref = register_url && flow.return_to ? `${register_url}?return_to=${encodeURIComponent(flow.return_to)}` : register_url;
448
+ return /* @__PURE__ */ jsxs4("div", { children: [
449
+ /* @__PURE__ */ jsx12(Messages, { flow }),
450
+ /* @__PURE__ */ jsxs4(Card, { className: "w-full max-w-md mx-auto", children: [
451
+ Header && /* @__PURE__ */ jsx12(CardHeader, { children: /* @__PURE__ */ jsx12(CardTitle, { className: "text-center pb-1", children: Header }) }),
452
+ /* @__PURE__ */ jsxs4(CardContent, { className: "space-y-6", children: [
453
+ oidcNodes.length > 0 && /* @__PURE__ */ jsx12(
454
+ OidcGroup,
455
+ {
456
+ nodes: sortNodes(oidcNodes),
457
+ flowAction: flow.ui.action,
458
+ flowMethod: flow.ui.method,
459
+ csrfToken,
460
+ groupIndex: 0,
461
+ groupName: "oidc"
462
+ }
463
+ ),
464
+ /* @__PURE__ */ jsxs4("div", { children: [
465
+ oidcNodes.length > 0 && /* @__PURE__ */ jsx12(Divider, { withText: true }),
466
+ /* @__PURE__ */ jsx12("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
467
+ csrfToken && /* @__PURE__ */ jsx12(HiddenInput, { node: csrfToken }),
468
+ identifierNodes.map((node, idx) => /* @__PURE__ */ jsx12(FormInput, { node }, idx)),
469
+ passwordInputNodes.map((node, idx) => /* @__PURE__ */ jsx12(FormInput, { node }, idx)),
470
+ submitButton && /* @__PURE__ */ jsx12(SubmitButton, { node: submitButton })
471
+ ] }) }),
472
+ register_url && /* @__PURE__ */ jsxs4("div", { className: "mt-4 text-center text-sm", children: [
473
+ "Don't have an account?",
474
+ " ",
475
+ /* @__PURE__ */ jsx12(
476
+ "a",
477
+ {
478
+ href: registerHref,
479
+ className: "text-primary underline-offset-4 hover:underline",
480
+ children: "Go to Register"
481
+ }
482
+ )
483
+ ] })
484
+ ] })
485
+ ] })
486
+ ] })
487
+ ] });
488
+ }
489
+
490
+ // src/form/registration.tsx
491
+ import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
492
+ function RegistrationForm({
493
+ flow,
494
+ Header,
495
+ login_url
496
+ }) {
497
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
498
+ const csrfToken = findCsrfToken(flow.ui.nodes);
499
+ const oidcNodes = nodesByGroup.oidc || [];
500
+ const defaultNodes = nodesByGroup.default || [];
501
+ const profileNodes = nodesByGroup.profile || [];
502
+ const passwordNodes = nodesByGroup.password || [];
503
+ const inputNodes = filterInputNodes(
504
+ sortNodes([...defaultNodes, ...passwordNodes])
505
+ );
506
+ const hiddenNodes = [...defaultNodes, ...passwordNodes].filter(
507
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "hidden" && node.attributes.name !== "csrf_token"
508
+ );
509
+ const submitButton = findSubmitButton(sortNodes(passwordNodes)) || findSubmitButton(sortNodes(profileNodes));
510
+ const loginHref = login_url && flow.return_to ? `${login_url}?return_to=${encodeURIComponent(flow.return_to)}` : login_url;
511
+ return /* @__PURE__ */ jsxs5("div", { children: [
512
+ /* @__PURE__ */ jsx13(Messages, { flow }),
513
+ /* @__PURE__ */ jsxs5(Card, { className: "w-full max-w-md mx-auto", children: [
514
+ Header && /* @__PURE__ */ jsx13(CardHeader, { children: /* @__PURE__ */ jsx13(CardTitle, { className: "text-center pb-1", children: Header }) }),
515
+ /* @__PURE__ */ jsxs5(CardContent, { className: "space-y-6", children: [
516
+ oidcNodes.length > 0 && /* @__PURE__ */ jsx13(
517
+ OidcGroup,
518
+ {
519
+ nodes: sortNodes(oidcNodes),
520
+ flowAction: flow.ui.action,
521
+ flowMethod: flow.ui.method,
522
+ csrfToken,
523
+ groupIndex: 0,
524
+ groupName: "oidc"
525
+ }
526
+ ),
527
+ /* @__PURE__ */ jsxs5("div", { children: [
528
+ oidcNodes.length > 0 && /* @__PURE__ */ jsx13(Divider, { withText: true }),
529
+ /* @__PURE__ */ jsx13("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ jsxs5("div", { className: "space-y-4", children: [
530
+ csrfToken && /* @__PURE__ */ jsx13(HiddenInput, { node: csrfToken }),
531
+ hiddenNodes.map((node, idx) => /* @__PURE__ */ jsx13(HiddenInput, { node }, `hidden-${idx}`)),
532
+ inputNodes.map((node, idx) => /* @__PURE__ */ jsx13(FormInput, { node }, idx)),
533
+ submitButton && /* @__PURE__ */ jsx13(SubmitButton, { node: submitButton })
534
+ ] }) }),
535
+ login_url && /* @__PURE__ */ jsxs5("div", { className: "mt-4 text-center text-sm", children: [
536
+ "Already have an account?",
537
+ " ",
538
+ /* @__PURE__ */ jsx13(
539
+ "a",
540
+ {
541
+ href: loginHref,
542
+ className: "text-primary underline-offset-4 hover:underline",
543
+ children: "Go to Login"
544
+ }
545
+ )
546
+ ] })
547
+ ] })
548
+ ] })
549
+ ] })
550
+ ] });
551
+ }
552
+
553
+ // src/form/verification.tsx
554
+ import * as React8 from "react";
555
+
556
+ // src/form/components/PinInput.tsx
557
+ import * as React7 from "react";
558
+ import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
559
+ function PinInput({
560
+ node,
561
+ length = 6,
562
+ initialValue = ""
563
+ }) {
564
+ if (!isUiNodeInputAttributes(node.attributes)) {
565
+ return null;
236
566
  }
237
- };
238
- var Messages = React6.forwardRef(
239
- ({ flow, className, ...props }, ref) => {
240
- if (!flow?.ui) return null;
241
- const allMessages = [];
242
- if (flow.ui.messages) {
243
- allMessages.push(...flow.ui.messages);
567
+ const [pins, setPins] = React7.useState(() => {
568
+ if (initialValue) {
569
+ const sanitized = initialValue.replace(/[^0-9]/g, "").slice(0, length);
570
+ const pinArray = Array(length).fill("");
571
+ for (let i = 0; i < sanitized.length; i++) {
572
+ pinArray[i] = sanitized[i];
573
+ }
574
+ return pinArray;
244
575
  }
245
- if (flow.ui.nodes) {
246
- flow.ui.nodes.forEach((node) => {
247
- if (node.messages) {
248
- allMessages.push(...node.messages);
249
- }
250
- });
576
+ return Array(length).fill("");
577
+ });
578
+ const inputRefs = React7.useRef([]);
579
+ const handleChange = (index, value) => {
580
+ const sanitizedValue = value.replace(/[^0-9]/g, "").slice(0, 1);
581
+ const newPins = [...pins];
582
+ newPins[index] = sanitizedValue;
583
+ setPins(newPins);
584
+ if (sanitizedValue && index < length - 1) {
585
+ inputRefs.current[index + 1]?.focus();
251
586
  }
252
- if (allMessages.length === 0) return null;
253
- return /* @__PURE__ */ jsx6(
254
- "div",
587
+ };
588
+ const handleKeyDown = (index, e) => {
589
+ if (e.key === "Backspace" && !pins[index] && index > 0) {
590
+ inputRefs.current[index - 1]?.focus();
591
+ }
592
+ if (e.key === "ArrowLeft" && index > 0) {
593
+ inputRefs.current[index - 1]?.focus();
594
+ }
595
+ if (e.key === "ArrowRight" && index < length - 1) {
596
+ inputRefs.current[index + 1]?.focus();
597
+ }
598
+ };
599
+ const handlePaste = (e) => {
600
+ e.preventDefault();
601
+ const pastedData = e.clipboardData.getData("text").replace(/[^0-9]/g, "");
602
+ const newPins = [...pins];
603
+ for (let i = 0; i < Math.min(pastedData.length, length); i++) {
604
+ newPins[i] = pastedData[i];
605
+ }
606
+ setPins(newPins);
607
+ const nextEmptyIndex = newPins.findIndex((pin) => !pin);
608
+ const focusIndex = nextEmptyIndex === -1 ? length - 1 : nextEmptyIndex;
609
+ inputRefs.current[focusIndex]?.focus();
610
+ };
611
+ const combinedValue = pins.join("");
612
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-2 mb-6", children: [
613
+ /* @__PURE__ */ jsx14("div", { className: "flex gap-2 justify-center", children: Array.from({ length }).map((_, index) => /* @__PURE__ */ jsx14(
614
+ "input",
255
615
  {
256
- ref,
257
- className: cn("w-full max-w-md mx-auto space-y-2 mb-4", className),
258
- ...props,
259
- children: allMessages.map((message) => /* @__PURE__ */ jsx6(Alert, { variant: getMessageVariant(message.type), children: /* @__PURE__ */ jsx6(AlertDescription, { children: message.text }) }, message.id))
616
+ ref: (el) => inputRefs.current[index] = el,
617
+ type: "text",
618
+ inputMode: "numeric",
619
+ maxLength: 1,
620
+ value: pins[index],
621
+ onChange: (e) => handleChange(index, e.target.value),
622
+ onKeyDown: (e) => handleKeyDown(index, e),
623
+ onPaste: index === 0 ? handlePaste : void 0,
624
+ disabled: isUiNodeInputAttributes(node.attributes) ? node.attributes.disabled : false,
625
+ className: cn(
626
+ "w-10 h-12 text-center text-lg font-semibold rounded-md border-2",
627
+ "border-input bg-background shadow-sm transition-all duration-200 outline-none",
628
+ "hover:border-ring/60",
629
+ "focus:border-ring focus:ring-4 focus:ring-ring/20 focus:scale-105",
630
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
631
+ "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
632
+ pins[index] && "border-primary bg-primary/5"
633
+ ),
634
+ "aria-label": `Digit ${index + 1}`
635
+ },
636
+ index
637
+ )) }),
638
+ /* @__PURE__ */ jsx14(
639
+ "input",
640
+ {
641
+ type: "hidden",
642
+ id: node.attributes.name,
643
+ name: node.attributes.name,
644
+ value: combinedValue,
645
+ required: node.attributes.required
260
646
  }
261
- );
647
+ )
648
+ ] });
649
+ }
650
+
651
+ // src/form/components/AnchorButton.tsx
652
+ import { jsx as jsx15 } from "react/jsx-runtime";
653
+ function AnchorButton({
654
+ node,
655
+ variant = "default",
656
+ className = "w-full"
657
+ }) {
658
+ if (node.type !== "a" || !("href" in node.attributes)) {
659
+ return null;
262
660
  }
263
- );
264
- Messages.displayName = "Messages";
661
+ const href = node.attributes.href;
662
+ const title = node.attributes.title;
663
+ const label = node.meta?.label;
664
+ const buttonText = (typeof title === "object" && title !== null && "text" in title ? title.text : typeof title === "string" ? title : null) || (label && typeof label === "object" && "text" in label ? label.text : null) || "Continue";
665
+ return /* @__PURE__ */ jsx15(Button, { variant, className, asChild: true, children: /* @__PURE__ */ jsx15("a", { href, children: buttonText }) });
666
+ }
265
667
 
266
- // src/form/index.tsx
267
- import { jsx as jsx7, jsxs } from "react/jsx-runtime";
268
- function isUiNodeInputAttributes(attributes) {
668
+ // src/form/verification.tsx
669
+ import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
670
+ function VerificationForm({
671
+ flow,
672
+ Header,
673
+ autoRedirect = true
674
+ }) {
675
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
676
+ const csrfToken = findCsrfToken(flow.ui.nodes);
677
+ const codeNodes = nodesByGroup.code || [];
678
+ const inputNodes = filterInputNodes(sortNodes(codeNodes));
679
+ const submitButton = findSubmitButton(sortNodes(codeNodes));
680
+ const anchorNode = findAnchorNode(sortNodes(codeNodes));
681
+ React8.useEffect(() => {
682
+ if (autoRedirect && anchorNode && anchorNode.type === "a" && "href" in anchorNode.attributes) {
683
+ const href = anchorNode.attributes.href;
684
+ if (href && typeof window !== "undefined") {
685
+ window.location.href = href;
686
+ }
687
+ }
688
+ }, [autoRedirect, anchorNode]);
689
+ return /* @__PURE__ */ jsxs7("div", { children: [
690
+ /* @__PURE__ */ jsx16(Messages, { flow }),
691
+ /* @__PURE__ */ jsxs7(Card, { className: "w-full max-w-md mx-auto", children: [
692
+ /* @__PURE__ */ jsx16(CardHeader, { children: /* @__PURE__ */ jsx16(CardTitle, { className: "text-center pb-1", children: Header || "Verification Code" }) }),
693
+ /* @__PURE__ */ jsx16(CardContent, { children: /* @__PURE__ */ jsx16("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ jsxs7("div", { className: "space-y-4", children: [
694
+ csrfToken && /* @__PURE__ */ jsx16(HiddenInput, { node: csrfToken }),
695
+ inputNodes.map((node, idx) => {
696
+ const isCodeInput = node.attributes.node_type === "input" && "name" in node.attributes && node.attributes.name === "code";
697
+ const initialValue = isCodeInput && "value" in node.attributes ? String(node.attributes.value || "") : "";
698
+ return isCodeInput ? /* @__PURE__ */ jsx16(
699
+ PinInput,
700
+ {
701
+ node,
702
+ length: 6,
703
+ initialValue
704
+ },
705
+ idx
706
+ ) : /* @__PURE__ */ jsx16(FormInput, { node }, idx);
707
+ }),
708
+ submitButton && /* @__PURE__ */ jsx16(SubmitButton, { node: submitButton }),
709
+ !submitButton && anchorNode && /* @__PURE__ */ jsx16(AnchorButton, { node: anchorNode })
710
+ ] }) }) })
711
+ ] })
712
+ ] });
713
+ }
714
+
715
+ // src/form/recovery.tsx
716
+ import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
717
+ function RecoveryForm({ flow, Header }) {
718
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
719
+ const csrfToken = findCsrfToken(flow.ui.nodes);
720
+ const codeNodes = nodesByGroup.code || [];
721
+ const linkNodes = nodesByGroup.link || [];
722
+ const activeNodes = codeNodes.length > 0 ? codeNodes : linkNodes;
723
+ const inputNodes = filterInputNodes(sortNodes(activeNodes));
724
+ const submitButton = findSubmitButton(sortNodes(activeNodes));
725
+ return /* @__PURE__ */ jsxs8("div", { children: [
726
+ /* @__PURE__ */ jsx17(Messages, { flow }),
727
+ /* @__PURE__ */ jsxs8(Card, { className: "w-full max-w-md mx-auto", children: [
728
+ Header && /* @__PURE__ */ jsx17(CardHeader, { children: /* @__PURE__ */ jsx17(CardTitle, { className: "text-center pb-1", children: Header }) }),
729
+ /* @__PURE__ */ jsx17(CardContent, { children: /* @__PURE__ */ jsx17("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ jsxs8("div", { className: "space-y-4", children: [
730
+ csrfToken && /* @__PURE__ */ jsx17(HiddenInput, { node: csrfToken }),
731
+ inputNodes.map((node, idx) => /* @__PURE__ */ jsx17(FormInput, { node }, idx)),
732
+ submitButton && /* @__PURE__ */ jsx17(SubmitButton, { node: submitButton })
733
+ ] }) }) })
734
+ ] })
735
+ ] });
736
+ }
737
+
738
+ // src/form/settings.tsx
739
+ import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
740
+ function isUiNodeInputAttributes2(attributes) {
269
741
  return attributes && typeof attributes === "object" && "name" in attributes && "type" in attributes;
270
742
  }
271
- function CustomFlowForm({ flow, Header }) {
743
+ function SettingsForm({ flow }) {
272
744
  const nodesByGroup = flow.ui.nodes.reduce((groups, node) => {
273
745
  const group = node.group || "default";
274
746
  if (!groups[group]) {
@@ -277,150 +749,128 @@ function CustomFlowForm({ flow, Header }) {
277
749
  groups[group].push(node);
278
750
  return groups;
279
751
  }, {});
280
- const oidcNodes = nodesByGroup.oidc || [];
281
- const regularNodes = Object.entries(nodesByGroup).filter(([group]) => group !== "oidc").flatMap(([, nodes]) => nodes);
282
- const csrfToken = regularNodes.find(
283
- (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.name === "csrf_token"
752
+ const csrfToken = flow.ui.nodes.find(
753
+ (node) => isUiNodeInputAttributes2(node.attributes) && node.attributes.name === "csrf_token"
284
754
  );
285
- const hasSubmitButton = flow.ui.nodes.some(
286
- (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit"
755
+ const settingsGroups = Object.entries(nodesByGroup).filter(
756
+ ([group]) => group !== "default" && group !== "oidc"
287
757
  );
288
- return /* @__PURE__ */ jsxs("div", { children: [
289
- /* @__PURE__ */ jsx7(Messages, { flow }),
290
- /* @__PURE__ */ jsxs(Card, { className: "w-full max-w-md mx-auto", children: [
291
- Header && /* @__PURE__ */ jsx7(CardHeader, { children: /* @__PURE__ */ jsx7(CardTitle, { className: "text-center pb-1", children: Header }) }),
292
- /* @__PURE__ */ jsxs(CardContent, { className: "space-y-6", children: [
293
- oidcNodes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
294
- oidcNodes.map((node, index) => {
295
- if (isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit") {
296
- return /* @__PURE__ */ jsxs(
297
- "form",
758
+ const groupTitles = {
759
+ profile: "Profile",
760
+ password: "Password",
761
+ totp: "Authenticator App",
762
+ webauthn: "Security Keys",
763
+ lookup_secret: "Backup Recovery Codes",
764
+ passkey: "Passkeys"
765
+ };
766
+ return /* @__PURE__ */ jsxs9("div", { className: "space-y-6", children: [
767
+ /* @__PURE__ */ jsx18(Messages, { flow }),
768
+ settingsGroups.map(([groupName, nodes]) => {
769
+ const submitButton = nodes.find(
770
+ (node) => isUiNodeInputAttributes2(node.attributes) && node.attributes.type === "submit"
771
+ );
772
+ const inputNodes = nodes.filter(
773
+ (node) => isUiNodeInputAttributes2(node.attributes) && node.attributes.type !== "submit" && node.attributes.type !== "hidden"
774
+ );
775
+ const imageNodes = nodes.filter((node) => node.type === "img");
776
+ const textNodes = nodes.filter((node) => node.type === "text");
777
+ return /* @__PURE__ */ jsxs9(Card, { className: "w-full max-w-2xl mx-auto", children: [
778
+ /* @__PURE__ */ jsx18(CardHeader, { children: /* @__PURE__ */ jsx18(CardTitle, { children: groupTitles[groupName] || groupName }) }),
779
+ /* @__PURE__ */ jsx18(CardContent, { children: /* @__PURE__ */ jsx18("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
780
+ csrfToken && isUiNodeInputAttributes2(csrfToken.attributes) && /* @__PURE__ */ jsx18(
781
+ "input",
782
+ {
783
+ name: csrfToken.attributes.name,
784
+ type: "hidden",
785
+ value: csrfToken.attributes.value || "",
786
+ readOnly: true
787
+ }
788
+ ),
789
+ imageNodes.map((node, index) => {
790
+ if (node.type === "img" && "src" in node.attributes) {
791
+ const imgAttrs = node.attributes;
792
+ return /* @__PURE__ */ jsx18(
793
+ "div",
298
794
  {
299
- action: flow.ui.action,
300
- method: flow.ui.method,
301
- className: "w-full",
302
- children: [
303
- csrfToken && isUiNodeInputAttributes(csrfToken.attributes) && /* @__PURE__ */ jsx7(
304
- "input",
305
- {
306
- name: csrfToken.attributes.name,
307
- type: "hidden",
308
- value: csrfToken.attributes.value || "",
309
- readOnly: true
310
- }
311
- ),
312
- /* @__PURE__ */ jsx7(
313
- Button,
314
- {
315
- type: "submit",
316
- name: node.attributes.name,
317
- value: node.attributes.value || "",
318
- variant: "outline",
319
- className: "w-full",
320
- children: node.meta.label?.text || node.attributes.value || "Sign in"
321
- }
322
- )
323
- ]
795
+ className: "flex justify-center",
796
+ children: /* @__PURE__ */ jsx18(
797
+ "img",
798
+ {
799
+ src: imgAttrs.src,
800
+ alt: node.meta.label?.text || "QR Code",
801
+ width: imgAttrs.width,
802
+ height: imgAttrs.height,
803
+ className: "border rounded-lg"
804
+ }
805
+ )
324
806
  },
325
- `oidc-${index}`
807
+ `img-${index}`
326
808
  );
327
809
  }
328
810
  return null;
329
811
  }),
330
- regularNodes.some(
331
- (node) => isUiNodeInputAttributes(node.attributes) && !["hidden", "submit"].includes(node.attributes.type)
332
- ) && /* @__PURE__ */ jsxs("div", { className: "relative my-6", children: [
333
- /* @__PURE__ */ jsx7("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx7("span", { className: "w-full border-t border-border" }) }),
334
- /* @__PURE__ */ jsx7("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx7("span", { className: "bg-background px-3 text-muted-foreground font-medium", children: "Or continue with email" }) })
335
- ] })
336
- ] }),
337
- /* @__PURE__ */ jsxs("form", { action: flow.ui.action, method: flow.ui.method, children: [
338
- regularNodes.map((node) => {
339
- if (isUiNodeInputAttributes(node.attributes)) {
340
- const isSubmitButton = node.attributes.type === "submit";
341
- const isHiddenField = node.attributes.type === "hidden";
342
- const isVisibleField = !isHiddenField && !isSubmitButton;
343
- if (isHiddenField) {
344
- return /* @__PURE__ */ jsx7(
345
- "input",
346
- {
347
- name: node.attributes.name,
348
- type: "hidden",
349
- value: node.attributes.value || "",
350
- readOnly: true
351
- },
352
- node.attributes.name
353
- );
354
- }
355
- if (isSubmitButton) {
356
- return /* @__PURE__ */ jsx7(
357
- Button,
812
+ textNodes.map((node, index) => {
813
+ if (node.type === "text" && "text" in node.attributes) {
814
+ const textContent = typeof node.attributes.text === "string" ? node.attributes.text : node.attributes.text?.text || "";
815
+ return /* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
816
+ node.meta.label?.text && /* @__PURE__ */ jsx18(Label, { className: "text-sm text-muted-foreground", children: node.meta.label.text }),
817
+ /* @__PURE__ */ jsx18("div", { className: "p-3 bg-muted rounded-md font-mono text-sm break-all", children: textContent })
818
+ ] }, `text-${index}`);
819
+ }
820
+ return null;
821
+ }),
822
+ inputNodes.map((node) => {
823
+ if (isUiNodeInputAttributes2(node.attributes)) {
824
+ return /* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
825
+ /* @__PURE__ */ jsxs9(Label, { htmlFor: node.attributes.name, children: [
826
+ node.meta.label?.text,
827
+ node.attributes.required && /* @__PURE__ */ jsx18("span", { className: "text-destructive ml-1", children: "*" })
828
+ ] }),
829
+ /* @__PURE__ */ jsx18(
830
+ Input,
358
831
  {
359
- type: "submit",
832
+ id: node.attributes.name,
360
833
  name: node.attributes.name,
361
- value: node.attributes.value || "",
362
- className: "w-full mt-2",
363
- children: node.meta.label?.text || node.attributes.value || "Submit"
364
- },
365
- node.attributes.name
366
- );
367
- }
368
- if (isVisibleField && [
369
- "default",
370
- "password",
371
- "code",
372
- "webauthn",
373
- "passkey",
374
- "totp",
375
- "lookup_secret",
376
- "profile"
377
- ].includes(node.group)) {
378
- return /* @__PURE__ */ jsxs(
379
- "div",
380
- {
381
- className: "space-y-2 mb-4",
382
- children: [
383
- /* @__PURE__ */ jsxs(Label, { htmlFor: node.attributes.name, children: [
384
- node.meta.label?.text,
385
- node.attributes.required && /* @__PURE__ */ jsx7("span", { className: "text-destructive ml-1", children: "*" })
386
- ] }),
387
- /* @__PURE__ */ jsx7(
388
- Input,
389
- {
390
- id: node.attributes.name,
391
- name: node.attributes.name,
392
- type: node.attributes.type,
393
- defaultValue: node.attributes.value || "",
394
- required: node.attributes.required,
395
- placeholder: `Enter your ${node.meta.label?.text?.toLowerCase() || node.attributes.name}`
396
- }
397
- )
398
- ]
399
- },
400
- node.meta.label?.id || node.attributes.name
401
- );
402
- }
834
+ type: node.attributes.type,
835
+ defaultValue: node.attributes.value || "",
836
+ required: node.attributes.required,
837
+ disabled: node.attributes.disabled,
838
+ autoComplete: node.attributes.autocomplete,
839
+ placeholder: `Enter ${node.meta.label?.text?.toLowerCase() || node.attributes.name}`
840
+ }
841
+ )
842
+ ] }, node.attributes.name);
403
843
  }
404
844
  return null;
405
845
  }),
406
- !hasSubmitButton && !oidcNodes.length && /* @__PURE__ */ jsx7(Button, { type: "submit", className: "w-full", children: "Submit" })
407
- ] })
408
- ] })
409
- ] })
846
+ submitButton && isUiNodeInputAttributes2(submitButton.attributes) && /* @__PURE__ */ jsx18(
847
+ Button,
848
+ {
849
+ type: "submit",
850
+ name: submitButton.attributes.name,
851
+ value: submitButton.attributes.value || "",
852
+ className: "w-full",
853
+ disabled: submitButton.attributes.disabled,
854
+ children: submitButton.meta.label?.text || submitButton.attributes.value || "Save"
855
+ }
856
+ )
857
+ ] }) }) })
858
+ ] }, groupName);
859
+ })
410
860
  ] });
411
861
  }
412
862
 
413
863
  // src/tenant-switcher/index.tsx
414
- import * as React8 from "react";
864
+ import * as React10 from "react";
415
865
 
416
866
  // src/components/ui/select.tsx
417
- import * as React7 from "react";
867
+ import * as React9 from "react";
418
868
  import * as SelectPrimitive from "@radix-ui/react-select";
419
869
  import { Check, ChevronDown, ChevronUp } from "lucide-react";
420
- import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
870
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
421
871
  var Select = SelectPrimitive.Root;
422
872
  var SelectValue = SelectPrimitive.Value;
423
- var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
873
+ var SelectTrigger = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs10(
424
874
  SelectPrimitive.Trigger,
425
875
  {
426
876
  ref,
@@ -431,12 +881,12 @@ var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) =
431
881
  ...props,
432
882
  children: [
433
883
  children,
434
- /* @__PURE__ */ jsx8(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx8(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
884
+ /* @__PURE__ */ jsx19(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx19(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
435
885
  ]
436
886
  }
437
887
  ));
438
888
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
439
- var SelectScrollUpButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
889
+ var SelectScrollUpButton = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
440
890
  SelectPrimitive.ScrollUpButton,
441
891
  {
442
892
  ref,
@@ -445,11 +895,11 @@ var SelectScrollUpButton = React7.forwardRef(({ className, ...props }, ref) => /
445
895
  className
446
896
  ),
447
897
  ...props,
448
- children: /* @__PURE__ */ jsx8(ChevronUp, { className: "h-4 w-4" })
898
+ children: /* @__PURE__ */ jsx19(ChevronUp, { className: "h-4 w-4" })
449
899
  }
450
900
  ));
451
901
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
452
- var SelectScrollDownButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
902
+ var SelectScrollDownButton = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
453
903
  SelectPrimitive.ScrollDownButton,
454
904
  {
455
905
  ref,
@@ -458,11 +908,11 @@ var SelectScrollDownButton = React7.forwardRef(({ className, ...props }, ref) =>
458
908
  className
459
909
  ),
460
910
  ...props,
461
- children: /* @__PURE__ */ jsx8(ChevronDown, { className: "h-4 w-4" })
911
+ children: /* @__PURE__ */ jsx19(ChevronDown, { className: "h-4 w-4" })
462
912
  }
463
913
  ));
464
914
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
465
- var SelectContent = React7.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx8(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs2(
915
+ var SelectContent = React9.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx19(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs10(
466
916
  SelectPrimitive.Content,
467
917
  {
468
918
  ref,
@@ -474,8 +924,8 @@ var SelectContent = React7.forwardRef(({ className, children, position = "popper
474
924
  position,
475
925
  ...props,
476
926
  children: [
477
- /* @__PURE__ */ jsx8(SelectScrollUpButton, {}),
478
- /* @__PURE__ */ jsx8(
927
+ /* @__PURE__ */ jsx19(SelectScrollUpButton, {}),
928
+ /* @__PURE__ */ jsx19(
479
929
  SelectPrimitive.Viewport,
480
930
  {
481
931
  className: cn(
@@ -485,12 +935,12 @@ var SelectContent = React7.forwardRef(({ className, children, position = "popper
485
935
  children
486
936
  }
487
937
  ),
488
- /* @__PURE__ */ jsx8(SelectScrollDownButton, {})
938
+ /* @__PURE__ */ jsx19(SelectScrollDownButton, {})
489
939
  ]
490
940
  }
491
941
  ) }));
492
942
  SelectContent.displayName = SelectPrimitive.Content.displayName;
493
- var SelectLabel = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
943
+ var SelectLabel = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
494
944
  SelectPrimitive.Label,
495
945
  {
496
946
  ref,
@@ -499,7 +949,7 @@ var SelectLabel = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE
499
949
  }
500
950
  ));
501
951
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
502
- var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
952
+ var SelectItem = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs10(
503
953
  SelectPrimitive.Item,
504
954
  {
505
955
  ref,
@@ -509,13 +959,13 @@ var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /
509
959
  ),
510
960
  ...props,
511
961
  children: [
512
- /* @__PURE__ */ jsx8("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx8(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx8(Check, { className: "h-4 w-4" }) }) }),
513
- /* @__PURE__ */ jsx8(SelectPrimitive.ItemText, { children })
962
+ /* @__PURE__ */ jsx19("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx19(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx19(Check, { className: "h-4 w-4" }) }) }),
963
+ /* @__PURE__ */ jsx19(SelectPrimitive.ItemText, { children })
514
964
  ]
515
965
  }
516
966
  ));
517
967
  SelectItem.displayName = SelectPrimitive.Item.displayName;
518
- var SelectSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
968
+ var SelectSeparator = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
519
969
  SelectPrimitive.Separator,
520
970
  {
521
971
  ref,
@@ -526,7 +976,7 @@ var SelectSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__
526
976
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
527
977
 
528
978
  // src/tenant-switcher/index.tsx
529
- import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
979
+ import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
530
980
  function SwitchActiveTenant({
531
981
  tenants,
532
982
  currentTenantId,
@@ -535,7 +985,7 @@ function SwitchActiveTenant({
535
985
  className,
536
986
  onTenantChange
537
987
  }) {
538
- const [isLoading, setIsLoading] = React8.useState(false);
988
+ const [isLoading, setIsLoading] = React10.useState(false);
539
989
  const handleTenantChange = async (tenantId) => {
540
990
  if (tenantId === currentTenantId) return;
541
991
  setIsLoading(true);
@@ -553,24 +1003,24 @@ function SwitchActiveTenant({
553
1003
  }
554
1004
  };
555
1005
  const currentTenant = tenants.find((tenant) => tenant.id === currentTenantId);
556
- return /* @__PURE__ */ jsxs3(
1006
+ return /* @__PURE__ */ jsxs11(
557
1007
  Select,
558
1008
  {
559
1009
  value: currentTenantId,
560
1010
  onValueChange: handleTenantChange,
561
1011
  disabled: isLoading,
562
1012
  children: [
563
- /* @__PURE__ */ jsx9(SelectTrigger, { className: cn("max-w-64", className), children: /* @__PURE__ */ jsx9(SelectValue, { placeholder, children: currentTenant ? currentTenant.name : placeholder }) }),
564
- /* @__PURE__ */ jsx9(SelectContent, { children: tenants.map((tenant) => /* @__PURE__ */ jsx9(SelectItem, { value: tenant.id, children: tenant.name }, tenant.id)) })
1013
+ /* @__PURE__ */ jsx20(SelectTrigger, { className: cn("max-w-64", className), children: /* @__PURE__ */ jsx20(SelectValue, { placeholder, children: currentTenant ? currentTenant.name : placeholder }) }),
1014
+ /* @__PURE__ */ jsx20(SelectContent, { children: tenants.map((tenant) => /* @__PURE__ */ jsx20(SelectItem, { value: tenant.id, children: tenant.name }, tenant.id)) })
565
1015
  ]
566
1016
  }
567
1017
  );
568
1018
  }
569
1019
 
570
1020
  // src/pricing-table/index.tsx
571
- import * as React9 from "react";
1021
+ import * as React11 from "react";
572
1022
  import { Check as Check2, Star, ChevronLeft, ChevronRight } from "lucide-react";
573
- import { Fragment, jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
1023
+ import { Fragment, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
574
1024
  var getCurrencySymbol = (currency) => {
575
1025
  const symbols = {
576
1026
  USD: "$",
@@ -611,7 +1061,7 @@ function PricingCard({
611
1061
  }) {
612
1062
  const ui = product.ui || {};
613
1063
  const isHighlighted = ui.highlighted;
614
- return /* @__PURE__ */ jsxs4(
1064
+ return /* @__PURE__ */ jsxs12(
615
1065
  "div",
616
1066
  {
617
1067
  className: cn(
@@ -619,11 +1069,11 @@ function PricingCard({
619
1069
  isHighlighted ? "relative" : ""
620
1070
  ),
621
1071
  children: [
622
- /* @__PURE__ */ jsx10("div", { className: "h-4 flex-shrink-0 relative", children: ui.badge && /* @__PURE__ */ jsx10("div", { className: "absolute top-0 left-1/2 transform -translate-x-1/2 z-10", children: /* @__PURE__ */ jsxs4("div", { className: "bg-primary text-primary-foreground px-3 py-1 rounded-full text-sm font-medium flex items-center gap-1 whitespace-nowrap shadow-md", children: [
623
- ui.badge === "Most Popular" && /* @__PURE__ */ jsx10(Star, { className: "w-3 h-3" }),
1072
+ /* @__PURE__ */ jsx21("div", { className: "h-4 flex-shrink-0 relative", children: ui.badge && /* @__PURE__ */ jsx21("div", { className: "absolute top-0 left-1/2 transform -translate-x-1/2 z-10", children: /* @__PURE__ */ jsxs12("div", { className: "bg-primary text-primary-foreground px-3 py-1 rounded-full text-sm font-medium flex items-center gap-1 whitespace-nowrap shadow-md", children: [
1073
+ ui.badge === "Most Popular" && /* @__PURE__ */ jsx21(Star, { className: "w-3 h-3" }),
624
1074
  ui.badge
625
1075
  ] }) }) }),
626
- /* @__PURE__ */ jsxs4(
1076
+ /* @__PURE__ */ jsxs12(
627
1077
  Card,
628
1078
  {
629
1079
  className: cn(
@@ -632,36 +1082,36 @@ function PricingCard({
632
1082
  isSelected && "ring-2 ring-primary"
633
1083
  ),
634
1084
  children: [
635
- /* @__PURE__ */ jsxs4(CardHeader, { className: "text-center", children: [
636
- /* @__PURE__ */ jsx10(CardTitle, { className: "text-xl font-bold", children: ui.display_name || product.name }),
637
- ui.tagline && /* @__PURE__ */ jsx10(CardDescription, { className: "text-base", children: ui.tagline })
1085
+ /* @__PURE__ */ jsxs12(CardHeader, { className: "text-center", children: [
1086
+ /* @__PURE__ */ jsx21(CardTitle, { className: "text-xl font-bold", children: ui.display_name || product.name }),
1087
+ ui.tagline && /* @__PURE__ */ jsx21(CardDescription, { className: "text-base", children: ui.tagline })
638
1088
  ] }),
639
- /* @__PURE__ */ jsxs4(CardContent, { className: "flex-1 space-y-6", children: [
640
- /* @__PURE__ */ jsxs4("div", { className: "text-center", children: [
641
- /* @__PURE__ */ jsx10("div", { className: "text-3xl font-bold", children: formatPrice(displayedPrice) }),
642
- /* @__PURE__ */ jsx10("div", { className: "text-sm text-muted-foreground", children: formatBillingPeriod(displayedPrice) })
1089
+ /* @__PURE__ */ jsxs12(CardContent, { className: "flex-1 space-y-6", children: [
1090
+ /* @__PURE__ */ jsxs12("div", { className: "text-center", children: [
1091
+ /* @__PURE__ */ jsx21("div", { className: "text-3xl font-bold", children: formatPrice(displayedPrice) }),
1092
+ /* @__PURE__ */ jsx21("div", { className: "text-sm text-muted-foreground", children: formatBillingPeriod(displayedPrice) })
643
1093
  ] }),
644
- (ui.features && ui.features.length > 0 || displayedPrice.ui?.features?.length > 0 || displayedPrice.ui?.limits?.length > 0) && /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
645
- ui.features && ui.features.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
646
- /* @__PURE__ */ jsx10("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Features" }),
647
- /* @__PURE__ */ jsx10("ul", { className: "space-y-2", children: ui.features.map((feature, index) => /* @__PURE__ */ jsxs4("li", { className: "flex items-start gap-2", children: [
648
- /* @__PURE__ */ jsx10(Check2, { className: "w-4 h-4 text-green-500 mt-0.5 flex-shrink-0" }),
649
- /* @__PURE__ */ jsx10("span", { className: "text-sm", children: feature })
1094
+ (ui.features && ui.features.length > 0 || displayedPrice.ui?.features?.length > 0 || displayedPrice.ui?.limits?.length > 0) && /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
1095
+ ui.features && ui.features.length > 0 && /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
1096
+ /* @__PURE__ */ jsx21("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Features" }),
1097
+ /* @__PURE__ */ jsx21("ul", { className: "space-y-2", children: ui.features.map((feature, index) => /* @__PURE__ */ jsxs12("li", { className: "flex items-start gap-2", children: [
1098
+ /* @__PURE__ */ jsx21(Check2, { className: "w-4 h-4 text-green-500 mt-0.5 flex-shrink-0" }),
1099
+ /* @__PURE__ */ jsx21("span", { className: "text-sm", children: feature })
650
1100
  ] }, index)) })
651
1101
  ] }),
652
- displayedPrice.ui?.features && displayedPrice.ui.features.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
653
- /* @__PURE__ */ jsx10("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "This Plan" }),
654
- /* @__PURE__ */ jsx10("ul", { className: "space-y-2", children: displayedPrice.ui.features.map(
655
- (feature, index) => /* @__PURE__ */ jsxs4("li", { className: "flex items-start gap-2", children: [
656
- /* @__PURE__ */ jsx10(Check2, { className: "w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0" }),
657
- /* @__PURE__ */ jsx10("span", { className: "text-sm", children: feature })
1102
+ displayedPrice.ui?.features && displayedPrice.ui.features.length > 0 && /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
1103
+ /* @__PURE__ */ jsx21("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "This Plan" }),
1104
+ /* @__PURE__ */ jsx21("ul", { className: "space-y-2", children: displayedPrice.ui.features.map(
1105
+ (feature, index) => /* @__PURE__ */ jsxs12("li", { className: "flex items-start gap-2", children: [
1106
+ /* @__PURE__ */ jsx21(Check2, { className: "w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0" }),
1107
+ /* @__PURE__ */ jsx21("span", { className: "text-sm", children: feature })
658
1108
  ] }, index)
659
1109
  ) })
660
1110
  ] }),
661
- displayedPrice.ui?.limits && displayedPrice.ui.limits.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
662
- /* @__PURE__ */ jsx10("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Usage Limits" }),
663
- /* @__PURE__ */ jsx10("ul", { className: "space-y-1", children: displayedPrice.ui.limits.map(
664
- (limit, index) => /* @__PURE__ */ jsx10(
1111
+ displayedPrice.ui?.limits && displayedPrice.ui.limits.length > 0 && /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
1112
+ /* @__PURE__ */ jsx21("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Usage Limits" }),
1113
+ /* @__PURE__ */ jsx21("ul", { className: "space-y-1", children: displayedPrice.ui.limits.map(
1114
+ (limit, index) => /* @__PURE__ */ jsx21(
665
1115
  "li",
666
1116
  {
667
1117
  className: "text-sm text-muted-foreground",
@@ -673,7 +1123,7 @@ function PricingCard({
673
1123
  ] })
674
1124
  ] })
675
1125
  ] }),
676
- /* @__PURE__ */ jsx10(CardFooter, { children: /* @__PURE__ */ jsx10(
1126
+ /* @__PURE__ */ jsx21(CardFooter, { children: /* @__PURE__ */ jsx21(
677
1127
  Button,
678
1128
  {
679
1129
  className: "w-full",
@@ -700,24 +1150,24 @@ function PricingTable({
700
1150
  showPricingToggle = false,
701
1151
  defaultInterval = "month"
702
1152
  }) {
703
- const [selectedInterval, setSelectedInterval] = React9.useState(defaultInterval);
704
- const [carouselIndex, setCarouselIndex] = React9.useState(0);
705
- const sortedProducts = React9.useMemo(
1153
+ const [selectedInterval, setSelectedInterval] = React11.useState(defaultInterval);
1154
+ const [carouselIndex, setCarouselIndex] = React11.useState(0);
1155
+ const sortedProducts = React11.useMemo(
706
1156
  () => [...products].sort(
707
1157
  (a, b) => (a.ui?.sort_order ?? 999) - (b.ui?.sort_order ?? 999)
708
1158
  ),
709
1159
  [products]
710
1160
  );
711
- const hasMultipleIntervals = React9.useMemo(
1161
+ const hasMultipleIntervals = React11.useMemo(
712
1162
  () => products.some(
713
1163
  (p) => new Set(p.prices.map((price) => price.interval)).size > 1
714
1164
  ),
715
1165
  [products]
716
1166
  );
717
- const getDisplayedPrice = (product) => product.prices.find((p) => p.interval === selectedInterval) || product.prices[0];
1167
+ const getDisplayedPrice = (product) => product.prices.find((price) => price.interval === selectedInterval) || product.prices[0];
718
1168
  const renderCard = (product) => {
719
1169
  const displayedPrice = getDisplayedPrice(product);
720
- return /* @__PURE__ */ jsx10(
1170
+ return /* @__PURE__ */ jsx21(
721
1171
  PricingCard,
722
1172
  {
723
1173
  product,
@@ -727,8 +1177,8 @@ function PricingTable({
727
1177
  }
728
1178
  );
729
1179
  };
730
- const desktopCarousel = /* @__PURE__ */ jsxs4("div", { className: "relative max-w-7xl mx-auto", children: [
731
- /* @__PURE__ */ jsx10(
1180
+ const desktopCarousel = /* @__PURE__ */ jsxs12("div", { className: "relative max-w-7xl mx-auto", children: [
1181
+ /* @__PURE__ */ jsx21(
732
1182
  Button,
733
1183
  {
734
1184
  variant: "ghost",
@@ -736,15 +1186,15 @@ function PricingTable({
736
1186
  className: "absolute left-0 top-1/2 transform -translate-y-1/2 -translate-x-4 z-10 bg-white shadow-lg border hover:bg-gray-50 disabled:opacity-50",
737
1187
  onClick: () => setCarouselIndex(Math.max(0, carouselIndex - 1)),
738
1188
  disabled: carouselIndex === 0,
739
- children: /* @__PURE__ */ jsx10(ChevronLeft, { className: "w-4 h-4" })
1189
+ children: /* @__PURE__ */ jsx21(ChevronLeft, { className: "w-4 h-4" })
740
1190
  }
741
1191
  ),
742
- /* @__PURE__ */ jsx10(
1192
+ /* @__PURE__ */ jsx21(
743
1193
  "div",
744
1194
  {
745
1195
  className: "overflow-hidden mx-auto",
746
1196
  style: { width: `${3 * CARD_WIDTH + 2 * GAP}px` },
747
- children: /* @__PURE__ */ jsx10(
1197
+ children: /* @__PURE__ */ jsx21(
748
1198
  "div",
749
1199
  {
750
1200
  className: "flex items-stretch transition-transform duration-300 ease-in-out",
@@ -752,7 +1202,7 @@ function PricingTable({
752
1202
  transform: `translateX(-${carouselIndex * (CARD_WIDTH + GAP)}px)`,
753
1203
  gap: `${GAP}px`
754
1204
  },
755
- children: sortedProducts.map((p) => /* @__PURE__ */ jsx10(
1205
+ children: sortedProducts.map((p) => /* @__PURE__ */ jsx21(
756
1206
  "div",
757
1207
  {
758
1208
  style: { width: `${CARD_WIDTH}px` },
@@ -765,7 +1215,7 @@ function PricingTable({
765
1215
  )
766
1216
  }
767
1217
  ),
768
- /* @__PURE__ */ jsx10(
1218
+ /* @__PURE__ */ jsx21(
769
1219
  Button,
770
1220
  {
771
1221
  variant: "ghost",
@@ -775,12 +1225,12 @@ function PricingTable({
775
1225
  Math.min(sortedProducts.length - 3, carouselIndex + 1)
776
1226
  ),
777
1227
  disabled: carouselIndex >= sortedProducts.length - 3,
778
- children: /* @__PURE__ */ jsx10(ChevronRight, { className: "w-4 h-4" })
1228
+ children: /* @__PURE__ */ jsx21(ChevronRight, { className: "w-4 h-4" })
779
1229
  }
780
1230
  ),
781
- /* @__PURE__ */ jsx10("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from(
1231
+ /* @__PURE__ */ jsx21("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from(
782
1232
  { length: Math.max(1, sortedProducts.length - 2) },
783
- (_, i) => /* @__PURE__ */ jsx10(
1233
+ (_, i) => /* @__PURE__ */ jsx21(
784
1234
  "button",
785
1235
  {
786
1236
  onClick: () => setCarouselIndex(i),
@@ -794,12 +1244,12 @@ function PricingTable({
794
1244
  )
795
1245
  ) })
796
1246
  ] });
797
- const staticLayout = /* @__PURE__ */ jsx10(
1247
+ const staticLayout = /* @__PURE__ */ jsx21(
798
1248
  "div",
799
1249
  {
800
1250
  className: "flex flex-row items-stretch justify-center",
801
1251
  style: { gap: `${GAP}px` },
802
- children: sortedProducts.map((p) => /* @__PURE__ */ jsx10(
1252
+ children: sortedProducts.map((p) => /* @__PURE__ */ jsx21(
803
1253
  "div",
804
1254
  {
805
1255
  style: { width: `${CARD_WIDTH}px` },
@@ -810,9 +1260,9 @@ function PricingTable({
810
1260
  ))
811
1261
  }
812
1262
  );
813
- return /* @__PURE__ */ jsxs4("div", { className: cn("w-full", className), children: [
814
- showPricingToggle && hasMultipleIntervals && /* @__PURE__ */ jsx10("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsxs4("div", { className: "flex bg-gray-100 p-1 rounded-lg", children: [
815
- /* @__PURE__ */ jsx10(
1263
+ return /* @__PURE__ */ jsxs12("div", { className: cn("w-full", className), children: [
1264
+ showPricingToggle && hasMultipleIntervals && /* @__PURE__ */ jsx21("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsxs12("div", { className: "flex bg-gray-100 p-1 rounded-lg", children: [
1265
+ /* @__PURE__ */ jsx21(
816
1266
  Button,
817
1267
  {
818
1268
  variant: selectedInterval === "month" ? "default" : "ghost",
@@ -822,7 +1272,7 @@ function PricingTable({
822
1272
  children: "Monthly"
823
1273
  }
824
1274
  ),
825
- /* @__PURE__ */ jsx10(
1275
+ /* @__PURE__ */ jsx21(
826
1276
  Button,
827
1277
  {
828
1278
  variant: selectedInterval === "year" ? "default" : "ghost",
@@ -833,20 +1283,20 @@ function PricingTable({
833
1283
  }
834
1284
  )
835
1285
  ] }) }),
836
- /* @__PURE__ */ jsxs4("div", { className: "lg:hidden relative", children: [
837
- /* @__PURE__ */ jsx10(
1286
+ /* @__PURE__ */ jsxs12("div", { className: "lg:hidden relative", children: [
1287
+ /* @__PURE__ */ jsx21(
838
1288
  "div",
839
1289
  {
840
1290
  className: "overflow-hidden mx-auto",
841
1291
  style: { width: `${CARD_WIDTH}px` },
842
- children: /* @__PURE__ */ jsx10(
1292
+ children: /* @__PURE__ */ jsx21(
843
1293
  "div",
844
1294
  {
845
1295
  className: "flex transition-transform duration-300 ease-in-out items-stretch",
846
1296
  style: {
847
1297
  transform: `translateX(-${carouselIndex * CARD_WIDTH}px)`
848
1298
  },
849
- children: sortedProducts.map((product) => /* @__PURE__ */ jsx10(
1299
+ children: sortedProducts.map((product) => /* @__PURE__ */ jsx21(
850
1300
  "div",
851
1301
  {
852
1302
  className: "flex-shrink-0",
@@ -859,8 +1309,8 @@ function PricingTable({
859
1309
  )
860
1310
  }
861
1311
  ),
862
- sortedProducts.length > 1 && /* @__PURE__ */ jsxs4(Fragment, { children: [
863
- /* @__PURE__ */ jsx10(
1312
+ sortedProducts.length > 1 && /* @__PURE__ */ jsxs12(Fragment, { children: [
1313
+ /* @__PURE__ */ jsx21(
864
1314
  Button,
865
1315
  {
866
1316
  variant: "ghost",
@@ -868,10 +1318,10 @@ function PricingTable({
868
1318
  className: "absolute left-0 top-1/2 -translate-y-1/2 -translate-x-2 z-10 bg-white shadow-lg border hover:bg-gray-50 disabled:opacity-50",
869
1319
  onClick: () => setCarouselIndex((prev) => Math.max(0, prev - 1)),
870
1320
  disabled: carouselIndex === 0,
871
- children: /* @__PURE__ */ jsx10(ChevronLeft, { className: "w-5 h-5" })
1321
+ children: /* @__PURE__ */ jsx21(ChevronLeft, { className: "w-5 h-5" })
872
1322
  }
873
1323
  ),
874
- /* @__PURE__ */ jsx10(
1324
+ /* @__PURE__ */ jsx21(
875
1325
  Button,
876
1326
  {
877
1327
  variant: "ghost",
@@ -881,10 +1331,10 @@ function PricingTable({
881
1331
  (prev) => Math.min(sortedProducts.length - 1, prev + 1)
882
1332
  ),
883
1333
  disabled: carouselIndex >= sortedProducts.length - 1,
884
- children: /* @__PURE__ */ jsx10(ChevronRight, { className: "w-5 h-5" })
1334
+ children: /* @__PURE__ */ jsx21(ChevronRight, { className: "w-5 h-5" })
885
1335
  }
886
1336
  ),
887
- /* @__PURE__ */ jsx10("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from({ length: sortedProducts.length }, (_, i) => /* @__PURE__ */ jsx10(
1337
+ /* @__PURE__ */ jsx21("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from({ length: sortedProducts.length }, (_, i) => /* @__PURE__ */ jsx21(
888
1338
  "button",
889
1339
  {
890
1340
  onClick: () => setCarouselIndex(i),
@@ -898,64 +1348,69 @@ function PricingTable({
898
1348
  )) })
899
1349
  ] })
900
1350
  ] }),
901
- /* @__PURE__ */ jsx10("div", { className: "hidden lg:block", children: sortedProducts.length <= 3 ? staticLayout : desktopCarousel })
1351
+ /* @__PURE__ */ jsx21("div", { className: "hidden lg:block", children: sortedProducts.length <= 3 ? staticLayout : desktopCarousel })
902
1352
  ] });
903
1353
  }
904
1354
 
905
1355
  // src/tenant-creator/index.tsx
906
- import { useState as useState3 } from "react";
907
- import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
1356
+ import { useState as useState4, useEffect as useEffect2 } from "react";
1357
+ import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
908
1358
  function TenantCreator({
909
1359
  config = {},
910
1360
  formActions = {},
911
1361
  className
912
1362
  }) {
913
- const [mode, setMode] = useState3(
914
- config.defaultMode || "create"
1363
+ const [mode, setMode] = useState4(
1364
+ !!config.joinForm?.token?.defaultValue === true ? "join" : config.defaultMode || "create"
915
1365
  );
916
- const [isLoading, setIsLoading] = useState3(false);
917
- const [organizationName, setOrganizationName] = useState3(
1366
+ const [isLoading, setIsLoading] = useState4(false);
1367
+ const [organizationName, setOrganizationName] = useState4(
918
1368
  config.createForm?.organizationName?.defaultValue || ""
919
1369
  );
920
- const [billingEmail, setBillingEmail] = useState3(
1370
+ const [billingEmail, setBillingEmail] = useState4(
921
1371
  config.createForm?.billingEmail?.defaultValue || ""
922
1372
  );
923
- const [token, setToken] = useState3(
1373
+ const [token, setToken] = useState4(
924
1374
  config.joinForm?.token?.defaultValue || ""
925
1375
  );
1376
+ useEffect2(() => {
1377
+ const urlParams = new URLSearchParams(window.location.search);
1378
+ const inviteToken = urlParams.get("invite_token");
1379
+ if (inviteToken) {
1380
+ setToken(inviteToken);
1381
+ setMode("join");
1382
+ }
1383
+ }, []);
926
1384
  const handleCreateSubmit = async (e) => {
927
1385
  e.preventDefault();
928
- if (!formActions.onCreateOrganization) return;
1386
+ if (!formActions.createOrganizationAction) return;
929
1387
  setIsLoading(true);
930
1388
  try {
931
- await formActions.onCreateOrganization({
932
- organizationName,
933
- billingEmail
934
- });
1389
+ const formData = new FormData(e.target);
1390
+ await formActions.createOrganizationAction(formData);
935
1391
  } finally {
936
1392
  setIsLoading(false);
937
1393
  }
938
1394
  };
939
1395
  const handleJoinSubmit = async (e) => {
940
1396
  e.preventDefault();
941
- if (!formActions.onJoinOrganization) return;
1397
+ if (!formActions.joinOrganizationAction) return;
942
1398
  setIsLoading(true);
943
1399
  try {
944
- await formActions.onJoinOrganization({
945
- token
946
- });
1400
+ const formData = new FormData(e.target);
1401
+ await formActions.joinOrganizationAction(formData);
947
1402
  } finally {
948
1403
  setIsLoading(false);
949
1404
  }
950
1405
  };
951
- return /* @__PURE__ */ jsxs5(Card, { className: cn("w-full max-w-md mx-auto", className), children: [
952
- /* @__PURE__ */ jsxs5(CardHeader, { children: [
953
- /* @__PURE__ */ jsx11(CardTitle, { children: "Organization Setup" }),
954
- /* @__PURE__ */ jsx11(CardDescription, { children: "Choose how you want to get started with your organization." })
1406
+ return /* @__PURE__ */ jsxs13(Card, { className: cn("w-full max-w-md mx-auto", className), children: [
1407
+ /* @__PURE__ */ jsxs13(CardHeader, { children: [
1408
+ /* @__PURE__ */ jsx22(CardTitle, { children: "Organization Setup" }),
1409
+ /* @__PURE__ */ jsx22(CardDescription, { children: "Choose how you want to get started with your organization." })
955
1410
  ] }),
956
- /* @__PURE__ */ jsxs5(CardContent, { className: "space-y-6", children: [
957
- /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-2 rounded-lg bg-muted p-1", children: [
958
- /* @__PURE__ */ jsxs5(
1411
+ /* @__PURE__ */ jsxs13(CardContent, { className: "space-y-6", children: [
1412
+ /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-2 rounded-lg bg-muted p-1", children: [
1413
+ /* @__PURE__ */ jsxs13(
959
1414
  "label",
960
1415
  {
961
1416
  className: cn(
@@ -964,7 +1419,7 @@ function TenantCreator({
964
1419
  isLoading && "pointer-events-none opacity-50"
965
1420
  ),
966
1421
  children: [
967
- /* @__PURE__ */ jsx11(
1422
+ /* @__PURE__ */ jsx22(
968
1423
  "input",
969
1424
  {
970
1425
  type: "radio",
@@ -980,7 +1435,7 @@ function TenantCreator({
980
1435
  ]
981
1436
  }
982
1437
  ),
983
- /* @__PURE__ */ jsxs5(
1438
+ /* @__PURE__ */ jsxs13(
984
1439
  "label",
985
1440
  {
986
1441
  className: cn(
@@ -989,7 +1444,7 @@ function TenantCreator({
989
1444
  isLoading && "pointer-events-none opacity-50"
990
1445
  ),
991
1446
  children: [
992
- /* @__PURE__ */ jsx11(
1447
+ /* @__PURE__ */ jsx22(
993
1448
  "input",
994
1449
  {
995
1450
  type: "radio",
@@ -1006,13 +1461,14 @@ function TenantCreator({
1006
1461
  }
1007
1462
  )
1008
1463
  ] }),
1009
- mode === "create" && /* @__PURE__ */ jsxs5("form", { onSubmit: handleCreateSubmit, className: "space-y-4", children: [
1010
- /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
1011
- /* @__PURE__ */ jsx11(Label, { htmlFor: "organizationName", children: config.createForm?.organizationName?.label || "Organization Name" }),
1012
- /* @__PURE__ */ jsx11(
1464
+ mode === "create" && /* @__PURE__ */ jsxs13("form", { onSubmit: handleCreateSubmit, className: "space-y-4", children: [
1465
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
1466
+ /* @__PURE__ */ jsx22(Label, { htmlFor: "organizationName", children: config.createForm?.organizationName?.label || "Organization Name" }),
1467
+ /* @__PURE__ */ jsx22(
1013
1468
  Input,
1014
1469
  {
1015
1470
  id: "organizationName",
1471
+ name: "organizationName",
1016
1472
  type: "text",
1017
1473
  placeholder: config.createForm?.organizationName?.placeholder || "Enter organization name",
1018
1474
  value: organizationName,
@@ -1022,12 +1478,13 @@ function TenantCreator({
1022
1478
  }
1023
1479
  )
1024
1480
  ] }),
1025
- /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
1026
- /* @__PURE__ */ jsx11(Label, { htmlFor: "billingEmail", children: config.createForm?.billingEmail?.label || "Billing Email" }),
1027
- /* @__PURE__ */ jsx11(
1481
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
1482
+ /* @__PURE__ */ jsx22(Label, { htmlFor: "billingEmail", children: config.createForm?.billingEmail?.label || "Billing Email" }),
1483
+ /* @__PURE__ */ jsx22(
1028
1484
  Input,
1029
1485
  {
1030
1486
  id: "billingEmail",
1487
+ name: "billingEmail",
1031
1488
  type: "email",
1032
1489
  placeholder: config.createForm?.billingEmail?.placeholder || "Enter billing email",
1033
1490
  value: billingEmail,
@@ -1037,15 +1494,16 @@ function TenantCreator({
1037
1494
  }
1038
1495
  )
1039
1496
  ] }),
1040
- /* @__PURE__ */ jsx11(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Creating..." : "Create Organization" })
1497
+ /* @__PURE__ */ jsx22(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Creating..." : "Create Organization" })
1041
1498
  ] }),
1042
- mode === "join" && /* @__PURE__ */ jsxs5("form", { onSubmit: handleJoinSubmit, className: "space-y-4", children: [
1043
- /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
1044
- /* @__PURE__ */ jsx11(Label, { htmlFor: "token", children: config.joinForm?.token?.label || "Invitation Token" }),
1045
- /* @__PURE__ */ jsx11(
1499
+ mode === "join" && /* @__PURE__ */ jsxs13("form", { onSubmit: handleJoinSubmit, className: "space-y-4", children: [
1500
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
1501
+ /* @__PURE__ */ jsx22(Label, { htmlFor: "token", children: config.joinForm?.token?.label || "Invitation Token" }),
1502
+ /* @__PURE__ */ jsx22(
1046
1503
  Input,
1047
1504
  {
1048
1505
  id: "token",
1506
+ name: "token",
1049
1507
  type: "text",
1050
1508
  placeholder: config.joinForm?.token?.placeholder || "Enter invitation token",
1051
1509
  value: token,
@@ -1055,14 +1513,25 @@ function TenantCreator({
1055
1513
  }
1056
1514
  )
1057
1515
  ] }),
1058
- /* @__PURE__ */ jsx11(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Joining..." : "Join Organization" })
1516
+ /* @__PURE__ */ jsx22(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Joining..." : "Join Organization" })
1059
1517
  ] })
1060
1518
  ] })
1061
1519
  ] });
1062
1520
  }
1063
1521
  export {
1064
- CustomFlowForm,
1522
+ LoginForm,
1065
1523
  PricingTable,
1524
+ RecoveryForm,
1525
+ RegistrationForm,
1526
+ SettingsForm,
1066
1527
  SwitchActiveTenant,
1067
- TenantCreator
1528
+ TenantCreator,
1529
+ VerificationForm,
1530
+ filterInputNodes,
1531
+ findAnchorNode,
1532
+ findCsrfToken,
1533
+ findSubmitButton,
1534
+ groupNodesByGroup,
1535
+ isUiNodeInputAttributes,
1536
+ sortNodes
1068
1537
  };