@omnibase/shadcn 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +318 -158
- package/dist/index.js +303 -143
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -166,101 +166,261 @@ function Label({
|
|
|
166
166
|
);
|
|
167
167
|
}
|
|
168
168
|
|
|
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"
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
defaultVariants: {
|
|
189
|
+
variant: "default"
|
|
190
|
+
}
|
|
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";
|
|
221
|
+
|
|
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";
|
|
236
|
+
}
|
|
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);
|
|
244
|
+
}
|
|
245
|
+
if (flow.ui.nodes) {
|
|
246
|
+
flow.ui.nodes.forEach((node) => {
|
|
247
|
+
if (node.messages) {
|
|
248
|
+
allMessages.push(...node.messages);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (allMessages.length === 0) return null;
|
|
253
|
+
return /* @__PURE__ */ jsx6(
|
|
254
|
+
"div",
|
|
255
|
+
{
|
|
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))
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
);
|
|
264
|
+
Messages.displayName = "Messages";
|
|
265
|
+
|
|
169
266
|
// src/form/index.tsx
|
|
170
|
-
import { jsx as
|
|
267
|
+
import { jsx as jsx7, jsxs } from "react/jsx-runtime";
|
|
171
268
|
function isUiNodeInputAttributes(attributes) {
|
|
172
269
|
return attributes && typeof attributes === "object" && "name" in attributes && "type" in attributes;
|
|
173
270
|
}
|
|
174
271
|
function CustomFlowForm({ flow, Header }) {
|
|
272
|
+
const nodesByGroup = flow.ui.nodes.reduce((groups, node) => {
|
|
273
|
+
const group = node.group || "default";
|
|
274
|
+
if (!groups[group]) {
|
|
275
|
+
groups[group] = [];
|
|
276
|
+
}
|
|
277
|
+
groups[group].push(node);
|
|
278
|
+
return groups;
|
|
279
|
+
}, {});
|
|
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"
|
|
284
|
+
);
|
|
175
285
|
const hasSubmitButton = flow.ui.nodes.some(
|
|
176
286
|
(node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit"
|
|
177
287
|
);
|
|
178
|
-
return /* @__PURE__ */
|
|
179
|
-
|
|
180
|
-
/* @__PURE__ */ jsxs(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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",
|
|
298
|
+
{
|
|
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
|
+
]
|
|
324
|
+
},
|
|
325
|
+
`oidc-${index}`
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
return null;
|
|
329
|
+
}),
|
|
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,
|
|
358
|
+
{
|
|
359
|
+
type: "submit",
|
|
360
|
+
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
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
}),
|
|
406
|
+
!hasSubmitButton && !oidcNodes.length && /* @__PURE__ */ jsx7(Button, { type: "submit", className: "w-full", children: "Submit" })
|
|
407
|
+
] })
|
|
408
|
+
] })
|
|
249
409
|
] })
|
|
250
|
-
] })
|
|
410
|
+
] });
|
|
251
411
|
}
|
|
252
412
|
|
|
253
413
|
// src/tenant-switcher/index.tsx
|
|
254
|
-
import * as
|
|
414
|
+
import * as React8 from "react";
|
|
255
415
|
|
|
256
416
|
// src/components/ui/select.tsx
|
|
257
|
-
import * as
|
|
417
|
+
import * as React7 from "react";
|
|
258
418
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
259
419
|
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
|
260
|
-
import { jsx as
|
|
420
|
+
import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
261
421
|
var Select = SelectPrimitive.Root;
|
|
262
422
|
var SelectValue = SelectPrimitive.Value;
|
|
263
|
-
var SelectTrigger =
|
|
423
|
+
var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
|
|
264
424
|
SelectPrimitive.Trigger,
|
|
265
425
|
{
|
|
266
426
|
ref,
|
|
@@ -271,12 +431,12 @@ var SelectTrigger = React5.forwardRef(({ className, children, ...props }, ref) =
|
|
|
271
431
|
...props,
|
|
272
432
|
children: [
|
|
273
433
|
children,
|
|
274
|
-
/* @__PURE__ */
|
|
434
|
+
/* @__PURE__ */ jsx8(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx8(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
|
|
275
435
|
]
|
|
276
436
|
}
|
|
277
437
|
));
|
|
278
438
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
279
|
-
var SelectScrollUpButton =
|
|
439
|
+
var SelectScrollUpButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
|
|
280
440
|
SelectPrimitive.ScrollUpButton,
|
|
281
441
|
{
|
|
282
442
|
ref,
|
|
@@ -285,11 +445,11 @@ var SelectScrollUpButton = React5.forwardRef(({ className, ...props }, ref) => /
|
|
|
285
445
|
className
|
|
286
446
|
),
|
|
287
447
|
...props,
|
|
288
|
-
children: /* @__PURE__ */
|
|
448
|
+
children: /* @__PURE__ */ jsx8(ChevronUp, { className: "h-4 w-4" })
|
|
289
449
|
}
|
|
290
450
|
));
|
|
291
451
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
292
|
-
var SelectScrollDownButton =
|
|
452
|
+
var SelectScrollDownButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
|
|
293
453
|
SelectPrimitive.ScrollDownButton,
|
|
294
454
|
{
|
|
295
455
|
ref,
|
|
@@ -298,11 +458,11 @@ var SelectScrollDownButton = React5.forwardRef(({ className, ...props }, ref) =>
|
|
|
298
458
|
className
|
|
299
459
|
),
|
|
300
460
|
...props,
|
|
301
|
-
children: /* @__PURE__ */
|
|
461
|
+
children: /* @__PURE__ */ jsx8(ChevronDown, { className: "h-4 w-4" })
|
|
302
462
|
}
|
|
303
463
|
));
|
|
304
464
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
305
|
-
var SelectContent =
|
|
465
|
+
var SelectContent = React7.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx8(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs2(
|
|
306
466
|
SelectPrimitive.Content,
|
|
307
467
|
{
|
|
308
468
|
ref,
|
|
@@ -314,8 +474,8 @@ var SelectContent = React5.forwardRef(({ className, children, position = "popper
|
|
|
314
474
|
position,
|
|
315
475
|
...props,
|
|
316
476
|
children: [
|
|
317
|
-
/* @__PURE__ */
|
|
318
|
-
/* @__PURE__ */
|
|
477
|
+
/* @__PURE__ */ jsx8(SelectScrollUpButton, {}),
|
|
478
|
+
/* @__PURE__ */ jsx8(
|
|
319
479
|
SelectPrimitive.Viewport,
|
|
320
480
|
{
|
|
321
481
|
className: cn(
|
|
@@ -325,12 +485,12 @@ var SelectContent = React5.forwardRef(({ className, children, position = "popper
|
|
|
325
485
|
children
|
|
326
486
|
}
|
|
327
487
|
),
|
|
328
|
-
/* @__PURE__ */
|
|
488
|
+
/* @__PURE__ */ jsx8(SelectScrollDownButton, {})
|
|
329
489
|
]
|
|
330
490
|
}
|
|
331
491
|
) }));
|
|
332
492
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
333
|
-
var SelectLabel =
|
|
493
|
+
var SelectLabel = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
|
|
334
494
|
SelectPrimitive.Label,
|
|
335
495
|
{
|
|
336
496
|
ref,
|
|
@@ -339,7 +499,7 @@ var SelectLabel = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
339
499
|
}
|
|
340
500
|
));
|
|
341
501
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
342
|
-
var SelectItem =
|
|
502
|
+
var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
|
|
343
503
|
SelectPrimitive.Item,
|
|
344
504
|
{
|
|
345
505
|
ref,
|
|
@@ -349,13 +509,13 @@ var SelectItem = React5.forwardRef(({ className, children, ...props }, ref) => /
|
|
|
349
509
|
),
|
|
350
510
|
...props,
|
|
351
511
|
children: [
|
|
352
|
-
/* @__PURE__ */
|
|
353
|
-
/* @__PURE__ */
|
|
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 })
|
|
354
514
|
]
|
|
355
515
|
}
|
|
356
516
|
));
|
|
357
517
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
358
|
-
var SelectSeparator =
|
|
518
|
+
var SelectSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
|
|
359
519
|
SelectPrimitive.Separator,
|
|
360
520
|
{
|
|
361
521
|
ref,
|
|
@@ -366,7 +526,7 @@ var SelectSeparator = React5.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
366
526
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
367
527
|
|
|
368
528
|
// src/tenant-switcher/index.tsx
|
|
369
|
-
import { jsx as
|
|
529
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
370
530
|
function SwitchActiveTenant({
|
|
371
531
|
tenants,
|
|
372
532
|
currentTenantId,
|
|
@@ -375,7 +535,7 @@ function SwitchActiveTenant({
|
|
|
375
535
|
className,
|
|
376
536
|
onTenantChange
|
|
377
537
|
}) {
|
|
378
|
-
const [isLoading, setIsLoading] =
|
|
538
|
+
const [isLoading, setIsLoading] = React8.useState(false);
|
|
379
539
|
const handleTenantChange = async (tenantId) => {
|
|
380
540
|
if (tenantId === currentTenantId) return;
|
|
381
541
|
setIsLoading(true);
|
|
@@ -400,17 +560,17 @@ function SwitchActiveTenant({
|
|
|
400
560
|
onValueChange: handleTenantChange,
|
|
401
561
|
disabled: isLoading,
|
|
402
562
|
children: [
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
/* @__PURE__ */
|
|
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)) })
|
|
405
565
|
]
|
|
406
566
|
}
|
|
407
567
|
);
|
|
408
568
|
}
|
|
409
569
|
|
|
410
570
|
// src/pricing-table/index.tsx
|
|
411
|
-
import * as
|
|
571
|
+
import * as React9 from "react";
|
|
412
572
|
import { Check as Check2, Star, ChevronLeft, ChevronRight } from "lucide-react";
|
|
413
|
-
import { Fragment, jsx as
|
|
573
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
414
574
|
var getCurrencySymbol = (currency) => {
|
|
415
575
|
const symbols = {
|
|
416
576
|
USD: "$",
|
|
@@ -459,8 +619,8 @@ function PricingCard({
|
|
|
459
619
|
isHighlighted ? "relative" : ""
|
|
460
620
|
),
|
|
461
621
|
children: [
|
|
462
|
-
/* @__PURE__ */
|
|
463
|
-
ui.badge === "Most Popular" && /* @__PURE__ */
|
|
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" }),
|
|
464
624
|
ui.badge
|
|
465
625
|
] }) }) }),
|
|
466
626
|
/* @__PURE__ */ jsxs4(
|
|
@@ -473,35 +633,35 @@ function PricingCard({
|
|
|
473
633
|
),
|
|
474
634
|
children: [
|
|
475
635
|
/* @__PURE__ */ jsxs4(CardHeader, { className: "text-center", children: [
|
|
476
|
-
/* @__PURE__ */
|
|
477
|
-
ui.tagline && /* @__PURE__ */
|
|
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 })
|
|
478
638
|
] }),
|
|
479
639
|
/* @__PURE__ */ jsxs4(CardContent, { className: "flex-1 space-y-6", children: [
|
|
480
640
|
/* @__PURE__ */ jsxs4("div", { className: "text-center", children: [
|
|
481
|
-
/* @__PURE__ */
|
|
482
|
-
/* @__PURE__ */
|
|
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) })
|
|
483
643
|
] }),
|
|
484
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: [
|
|
485
645
|
ui.features && ui.features.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
486
|
-
/* @__PURE__ */
|
|
487
|
-
/* @__PURE__ */
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
/* @__PURE__ */
|
|
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 })
|
|
490
650
|
] }, index)) })
|
|
491
651
|
] }),
|
|
492
652
|
displayedPrice.ui?.features && displayedPrice.ui.features.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
493
|
-
/* @__PURE__ */
|
|
494
|
-
/* @__PURE__ */
|
|
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(
|
|
495
655
|
(feature, index) => /* @__PURE__ */ jsxs4("li", { className: "flex items-start gap-2", children: [
|
|
496
|
-
/* @__PURE__ */
|
|
497
|
-
/* @__PURE__ */
|
|
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 })
|
|
498
658
|
] }, index)
|
|
499
659
|
) })
|
|
500
660
|
] }),
|
|
501
661
|
displayedPrice.ui?.limits && displayedPrice.ui.limits.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
502
|
-
/* @__PURE__ */
|
|
503
|
-
/* @__PURE__ */
|
|
504
|
-
(limit, index) => /* @__PURE__ */
|
|
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(
|
|
505
665
|
"li",
|
|
506
666
|
{
|
|
507
667
|
className: "text-sm text-muted-foreground",
|
|
@@ -513,7 +673,7 @@ function PricingCard({
|
|
|
513
673
|
] })
|
|
514
674
|
] })
|
|
515
675
|
] }),
|
|
516
|
-
/* @__PURE__ */
|
|
676
|
+
/* @__PURE__ */ jsx10(CardFooter, { children: /* @__PURE__ */ jsx10(
|
|
517
677
|
Button,
|
|
518
678
|
{
|
|
519
679
|
className: "w-full",
|
|
@@ -540,15 +700,15 @@ function PricingTable({
|
|
|
540
700
|
showPricingToggle = false,
|
|
541
701
|
defaultInterval = "month"
|
|
542
702
|
}) {
|
|
543
|
-
const [selectedInterval, setSelectedInterval] =
|
|
544
|
-
const [carouselIndex, setCarouselIndex] =
|
|
545
|
-
const sortedProducts =
|
|
703
|
+
const [selectedInterval, setSelectedInterval] = React9.useState(defaultInterval);
|
|
704
|
+
const [carouselIndex, setCarouselIndex] = React9.useState(0);
|
|
705
|
+
const sortedProducts = React9.useMemo(
|
|
546
706
|
() => [...products].sort(
|
|
547
707
|
(a, b) => (a.ui?.sort_order ?? 999) - (b.ui?.sort_order ?? 999)
|
|
548
708
|
),
|
|
549
709
|
[products]
|
|
550
710
|
);
|
|
551
|
-
const hasMultipleIntervals =
|
|
711
|
+
const hasMultipleIntervals = React9.useMemo(
|
|
552
712
|
() => products.some(
|
|
553
713
|
(p) => new Set(p.prices.map((price) => price.interval)).size > 1
|
|
554
714
|
),
|
|
@@ -557,7 +717,7 @@ function PricingTable({
|
|
|
557
717
|
const getDisplayedPrice = (product) => product.prices.find((p) => p.interval === selectedInterval) || product.prices[0];
|
|
558
718
|
const renderCard = (product) => {
|
|
559
719
|
const displayedPrice = getDisplayedPrice(product);
|
|
560
|
-
return /* @__PURE__ */
|
|
720
|
+
return /* @__PURE__ */ jsx10(
|
|
561
721
|
PricingCard,
|
|
562
722
|
{
|
|
563
723
|
product,
|
|
@@ -568,7 +728,7 @@ function PricingTable({
|
|
|
568
728
|
);
|
|
569
729
|
};
|
|
570
730
|
const desktopCarousel = /* @__PURE__ */ jsxs4("div", { className: "relative max-w-7xl mx-auto", children: [
|
|
571
|
-
/* @__PURE__ */
|
|
731
|
+
/* @__PURE__ */ jsx10(
|
|
572
732
|
Button,
|
|
573
733
|
{
|
|
574
734
|
variant: "ghost",
|
|
@@ -576,15 +736,15 @@ function PricingTable({
|
|
|
576
736
|
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",
|
|
577
737
|
onClick: () => setCarouselIndex(Math.max(0, carouselIndex - 1)),
|
|
578
738
|
disabled: carouselIndex === 0,
|
|
579
|
-
children: /* @__PURE__ */
|
|
739
|
+
children: /* @__PURE__ */ jsx10(ChevronLeft, { className: "w-4 h-4" })
|
|
580
740
|
}
|
|
581
741
|
),
|
|
582
|
-
/* @__PURE__ */
|
|
742
|
+
/* @__PURE__ */ jsx10(
|
|
583
743
|
"div",
|
|
584
744
|
{
|
|
585
745
|
className: "overflow-hidden mx-auto",
|
|
586
746
|
style: { width: `${3 * CARD_WIDTH + 2 * GAP}px` },
|
|
587
|
-
children: /* @__PURE__ */
|
|
747
|
+
children: /* @__PURE__ */ jsx10(
|
|
588
748
|
"div",
|
|
589
749
|
{
|
|
590
750
|
className: "flex items-stretch transition-transform duration-300 ease-in-out",
|
|
@@ -592,7 +752,7 @@ function PricingTable({
|
|
|
592
752
|
transform: `translateX(-${carouselIndex * (CARD_WIDTH + GAP)}px)`,
|
|
593
753
|
gap: `${GAP}px`
|
|
594
754
|
},
|
|
595
|
-
children: sortedProducts.map((p) => /* @__PURE__ */
|
|
755
|
+
children: sortedProducts.map((p) => /* @__PURE__ */ jsx10(
|
|
596
756
|
"div",
|
|
597
757
|
{
|
|
598
758
|
style: { width: `${CARD_WIDTH}px` },
|
|
@@ -605,7 +765,7 @@ function PricingTable({
|
|
|
605
765
|
)
|
|
606
766
|
}
|
|
607
767
|
),
|
|
608
|
-
/* @__PURE__ */
|
|
768
|
+
/* @__PURE__ */ jsx10(
|
|
609
769
|
Button,
|
|
610
770
|
{
|
|
611
771
|
variant: "ghost",
|
|
@@ -615,12 +775,12 @@ function PricingTable({
|
|
|
615
775
|
Math.min(sortedProducts.length - 3, carouselIndex + 1)
|
|
616
776
|
),
|
|
617
777
|
disabled: carouselIndex >= sortedProducts.length - 3,
|
|
618
|
-
children: /* @__PURE__ */
|
|
778
|
+
children: /* @__PURE__ */ jsx10(ChevronRight, { className: "w-4 h-4" })
|
|
619
779
|
}
|
|
620
780
|
),
|
|
621
|
-
/* @__PURE__ */
|
|
781
|
+
/* @__PURE__ */ jsx10("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from(
|
|
622
782
|
{ length: Math.max(1, sortedProducts.length - 2) },
|
|
623
|
-
(_, i) => /* @__PURE__ */
|
|
783
|
+
(_, i) => /* @__PURE__ */ jsx10(
|
|
624
784
|
"button",
|
|
625
785
|
{
|
|
626
786
|
onClick: () => setCarouselIndex(i),
|
|
@@ -634,12 +794,12 @@ function PricingTable({
|
|
|
634
794
|
)
|
|
635
795
|
) })
|
|
636
796
|
] });
|
|
637
|
-
const staticLayout = /* @__PURE__ */
|
|
797
|
+
const staticLayout = /* @__PURE__ */ jsx10(
|
|
638
798
|
"div",
|
|
639
799
|
{
|
|
640
800
|
className: "flex flex-row items-stretch justify-center",
|
|
641
801
|
style: { gap: `${GAP}px` },
|
|
642
|
-
children: sortedProducts.map((p) => /* @__PURE__ */
|
|
802
|
+
children: sortedProducts.map((p) => /* @__PURE__ */ jsx10(
|
|
643
803
|
"div",
|
|
644
804
|
{
|
|
645
805
|
style: { width: `${CARD_WIDTH}px` },
|
|
@@ -651,8 +811,8 @@ function PricingTable({
|
|
|
651
811
|
}
|
|
652
812
|
);
|
|
653
813
|
return /* @__PURE__ */ jsxs4("div", { className: cn("w-full", className), children: [
|
|
654
|
-
showPricingToggle && hasMultipleIntervals && /* @__PURE__ */
|
|
655
|
-
/* @__PURE__ */
|
|
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(
|
|
656
816
|
Button,
|
|
657
817
|
{
|
|
658
818
|
variant: selectedInterval === "month" ? "default" : "ghost",
|
|
@@ -662,7 +822,7 @@ function PricingTable({
|
|
|
662
822
|
children: "Monthly"
|
|
663
823
|
}
|
|
664
824
|
),
|
|
665
|
-
/* @__PURE__ */
|
|
825
|
+
/* @__PURE__ */ jsx10(
|
|
666
826
|
Button,
|
|
667
827
|
{
|
|
668
828
|
variant: selectedInterval === "year" ? "default" : "ghost",
|
|
@@ -674,19 +834,19 @@ function PricingTable({
|
|
|
674
834
|
)
|
|
675
835
|
] }) }),
|
|
676
836
|
/* @__PURE__ */ jsxs4("div", { className: "lg:hidden relative", children: [
|
|
677
|
-
/* @__PURE__ */
|
|
837
|
+
/* @__PURE__ */ jsx10(
|
|
678
838
|
"div",
|
|
679
839
|
{
|
|
680
840
|
className: "overflow-hidden mx-auto",
|
|
681
841
|
style: { width: `${CARD_WIDTH}px` },
|
|
682
|
-
children: /* @__PURE__ */
|
|
842
|
+
children: /* @__PURE__ */ jsx10(
|
|
683
843
|
"div",
|
|
684
844
|
{
|
|
685
845
|
className: "flex transition-transform duration-300 ease-in-out items-stretch",
|
|
686
846
|
style: {
|
|
687
847
|
transform: `translateX(-${carouselIndex * CARD_WIDTH}px)`
|
|
688
848
|
},
|
|
689
|
-
children: sortedProducts.map((product) => /* @__PURE__ */
|
|
849
|
+
children: sortedProducts.map((product) => /* @__PURE__ */ jsx10(
|
|
690
850
|
"div",
|
|
691
851
|
{
|
|
692
852
|
className: "flex-shrink-0",
|
|
@@ -700,7 +860,7 @@ function PricingTable({
|
|
|
700
860
|
}
|
|
701
861
|
),
|
|
702
862
|
sortedProducts.length > 1 && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
703
|
-
/* @__PURE__ */
|
|
863
|
+
/* @__PURE__ */ jsx10(
|
|
704
864
|
Button,
|
|
705
865
|
{
|
|
706
866
|
variant: "ghost",
|
|
@@ -708,10 +868,10 @@ function PricingTable({
|
|
|
708
868
|
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",
|
|
709
869
|
onClick: () => setCarouselIndex((prev) => Math.max(0, prev - 1)),
|
|
710
870
|
disabled: carouselIndex === 0,
|
|
711
|
-
children: /* @__PURE__ */
|
|
871
|
+
children: /* @__PURE__ */ jsx10(ChevronLeft, { className: "w-5 h-5" })
|
|
712
872
|
}
|
|
713
873
|
),
|
|
714
|
-
/* @__PURE__ */
|
|
874
|
+
/* @__PURE__ */ jsx10(
|
|
715
875
|
Button,
|
|
716
876
|
{
|
|
717
877
|
variant: "ghost",
|
|
@@ -721,10 +881,10 @@ function PricingTable({
|
|
|
721
881
|
(prev) => Math.min(sortedProducts.length - 1, prev + 1)
|
|
722
882
|
),
|
|
723
883
|
disabled: carouselIndex >= sortedProducts.length - 1,
|
|
724
|
-
children: /* @__PURE__ */
|
|
884
|
+
children: /* @__PURE__ */ jsx10(ChevronRight, { className: "w-5 h-5" })
|
|
725
885
|
}
|
|
726
886
|
),
|
|
727
|
-
/* @__PURE__ */
|
|
887
|
+
/* @__PURE__ */ jsx10("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from({ length: sortedProducts.length }, (_, i) => /* @__PURE__ */ jsx10(
|
|
728
888
|
"button",
|
|
729
889
|
{
|
|
730
890
|
onClick: () => setCarouselIndex(i),
|
|
@@ -738,7 +898,7 @@ function PricingTable({
|
|
|
738
898
|
)) })
|
|
739
899
|
] })
|
|
740
900
|
] }),
|
|
741
|
-
/* @__PURE__ */
|
|
901
|
+
/* @__PURE__ */ jsx10("div", { className: "hidden lg:block", children: sortedProducts.length <= 3 ? staticLayout : desktopCarousel })
|
|
742
902
|
] });
|
|
743
903
|
}
|
|
744
904
|
export {
|