@olwiba/ui 0.1.10 → 0.1.12
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.d.ts +15 -3
- package/dist/index.js +38 -35
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/app/AuthSection.tsx +2 -1
- package/src/components/BrandColorSwitchMinimal.tsx +8 -2
- package/src/components/FlowBracket.tsx +21 -13
- package/src/components/PricingCard.tsx +9 -1
- package/src/marketing/Navbar.tsx +11 -12
- package/src/marketing/PricingSection.tsx +7 -0
package/dist/index.d.ts
CHANGED
|
@@ -521,10 +521,14 @@ interface PricingCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
521
521
|
cta: string;
|
|
522
522
|
highlighted?: boolean;
|
|
523
523
|
disabled?: boolean;
|
|
524
|
+
/** Disables only the CTA button, leaving the rest of the card interactive. */
|
|
525
|
+
ctaDisabled?: boolean;
|
|
524
526
|
badge?: React.ReactNode;
|
|
527
|
+
/** Rendered directly below the CTA button (e.g. a "Get notified" link). */
|
|
528
|
+
footer?: React.ReactNode;
|
|
525
529
|
onSelect?: () => void;
|
|
526
530
|
}
|
|
527
|
-
declare function PricingCard({ name, price, period, description, features, cta, highlighted, disabled, badge, onSelect, className, ...props }: PricingCardProps): react_jsx_runtime.JSX.Element;
|
|
531
|
+
declare function PricingCard({ name, price, period, description, features, cta, highlighted, disabled, ctaDisabled, badge, footer, onSelect, className, ...props }: PricingCardProps): react_jsx_runtime.JSX.Element;
|
|
528
532
|
|
|
529
533
|
interface PricingPlan {
|
|
530
534
|
name: string;
|
|
@@ -534,6 +538,8 @@ interface PricingPlan {
|
|
|
534
538
|
cta: string;
|
|
535
539
|
highlighted?: boolean;
|
|
536
540
|
disabled?: boolean;
|
|
541
|
+
/** Disables only the CTA button, leaving the rest of the card interactive. */
|
|
542
|
+
ctaDisabled?: boolean;
|
|
537
543
|
features: PricingFeature[];
|
|
538
544
|
/** Overrides computed price display (e.g. "$?" for community/reach-out tiers). */
|
|
539
545
|
priceDisplay?: string;
|
|
@@ -551,8 +557,10 @@ interface PricingSectionProps {
|
|
|
551
557
|
footnote?: string;
|
|
552
558
|
mode?: 'subscription' | 'one-time';
|
|
553
559
|
foundingDeadline?: string;
|
|
560
|
+
/** Rendered below each plan's CTA button (e.g. a "Get notified" link). */
|
|
561
|
+
renderPlanFooter?: (plan: PricingPlan) => React.ReactNode;
|
|
554
562
|
}
|
|
555
|
-
declare function PricingSection({ title, description, badge, plans, saveBadge, isAuthenticated, renderLink, footnote, mode, foundingDeadline, }: PricingSectionProps): react_jsx_runtime.JSX.Element;
|
|
563
|
+
declare function PricingSection({ title, description, badge, plans, saveBadge, isAuthenticated, renderLink, footnote, mode, foundingDeadline, renderPlanFooter, }: PricingSectionProps): react_jsx_runtime.JSX.Element;
|
|
556
564
|
|
|
557
565
|
interface TestimonialsSectionProps {
|
|
558
566
|
title?: string;
|
|
@@ -1056,6 +1064,10 @@ interface FlowBracketProps {
|
|
|
1056
1064
|
* Defaults to 8 (near the top of the first child).
|
|
1057
1065
|
*/
|
|
1058
1066
|
anchorTop?: number;
|
|
1067
|
+
/** Per-side override for the top anchor of the left bracket. Falls back to anchorTop. */
|
|
1068
|
+
anchorTopLeft?: number;
|
|
1069
|
+
/** Per-side override for the top anchor of the right bracket. Falls back to anchorTop. */
|
|
1070
|
+
anchorTopRight?: number;
|
|
1059
1071
|
/**
|
|
1060
1072
|
* Vertical anchor for the bottom connection as a percentage of the wrapper height (0–100).
|
|
1061
1073
|
* Defaults to 92 (near the bottom of the last child).
|
|
@@ -1102,7 +1114,7 @@ interface FlowBracketProps {
|
|
|
1102
1114
|
* they render at a consistent pixel size regardless of the bracket SVG's aspect
|
|
1103
1115
|
* ratio (which spans the full section height with preserveAspectRatio="none").
|
|
1104
1116
|
*/
|
|
1105
|
-
declare function FlowBracket({ anchorTop, anchorBottom, extent, arrow, color, colorLeft, colorRight, left, right, animate, animateDur, reverseRight, style, className, children, }: FlowBracketProps): react_jsx_runtime.JSX.Element;
|
|
1117
|
+
declare function FlowBracket({ anchorTop, anchorTopLeft, anchorTopRight, anchorBottom, extent, arrow, color, colorLeft, colorRight, left, right, animate, animateDur, reverseRight, style, className, children, }: FlowBracketProps): react_jsx_runtime.JSX.Element;
|
|
1106
1118
|
|
|
1107
1119
|
interface FullPageSpinnerProps {
|
|
1108
1120
|
message?: string;
|
package/dist/index.js
CHANGED
|
@@ -498,7 +498,8 @@ function DefaultForm({
|
|
|
498
498
|
const hasPrefill = !!(defaultEmail || defaultPassword);
|
|
499
499
|
const prefillStyle = (active) => active ? { animation: "auth-prefill 1.6s ease-out 0.35s 1 both" } : void 0;
|
|
500
500
|
return /* @__PURE__ */ jsxs(Card, { className: "w-full", children: [
|
|
501
|
-
hasPrefill &&
|
|
501
|
+
hasPrefill && // Theme tokens hold full color values (oklch), so opacity must come from color-mix, not hsl(var()/a)
|
|
502
|
+
/* @__PURE__ */ jsx("style", { children: `@keyframes auth-prefill{0%{box-shadow:0 0 0 0 transparent}40%{box-shadow:0 0 0 3px color-mix(in oklab,var(--primary) 45%,transparent),0 0 16px 2px color-mix(in oklab,var(--primary) 35%,transparent)}100%{box-shadow:0 0 0 0 transparent}}` }),
|
|
502
503
|
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
503
504
|
brand && /* @__PURE__ */ jsx("div", { className: "mb-2", children: brand }),
|
|
504
505
|
/* @__PURE__ */ jsx(CardTitle, { children: isSignUp ? "Create an account" : "Sign in" }),
|
|
@@ -1455,7 +1456,9 @@ function PricingCard({
|
|
|
1455
1456
|
cta,
|
|
1456
1457
|
highlighted = false,
|
|
1457
1458
|
disabled = false,
|
|
1459
|
+
ctaDisabled = false,
|
|
1458
1460
|
badge,
|
|
1461
|
+
footer,
|
|
1459
1462
|
onSelect,
|
|
1460
1463
|
className,
|
|
1461
1464
|
...props
|
|
@@ -1488,10 +1491,11 @@ function PricingCard({
|
|
|
1488
1491
|
variant: highlighted ? "default" : "outline",
|
|
1489
1492
|
className: "mt-6 w-full",
|
|
1490
1493
|
onClick: onSelect,
|
|
1491
|
-
disabled,
|
|
1494
|
+
disabled: disabled || ctaDisabled,
|
|
1492
1495
|
children: cta
|
|
1493
1496
|
}
|
|
1494
1497
|
),
|
|
1498
|
+
footer && /* @__PURE__ */ jsx("div", { className: "mt-3 text-center text-sm", children: footer }),
|
|
1495
1499
|
/* @__PURE__ */ jsx(Separator, { className: "my-6" }),
|
|
1496
1500
|
/* @__PURE__ */ jsx("ul", { className: "space-y-3 text-sm", children: features.map((feat) => /* @__PURE__ */ jsx("li", { className: "flex items-center gap-2", children: feat.included ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1497
1501
|
/* @__PURE__ */ jsx(Check, { className: "size-4 shrink-0 text-primary" }),
|
|
@@ -1583,7 +1587,8 @@ function PricingSection({
|
|
|
1583
1587
|
renderLink = defaultRenderLink7,
|
|
1584
1588
|
footnote,
|
|
1585
1589
|
mode = "subscription",
|
|
1586
|
-
foundingDeadline
|
|
1590
|
+
foundingDeadline,
|
|
1591
|
+
renderPlanFooter
|
|
1587
1592
|
}) {
|
|
1588
1593
|
const [annual, setAnnual] = React29.useState(false);
|
|
1589
1594
|
const isOneTime = mode === "one-time";
|
|
@@ -1647,7 +1652,9 @@ function PricingSection({
|
|
|
1647
1652
|
cta: plan.cta,
|
|
1648
1653
|
highlighted: plan.highlighted,
|
|
1649
1654
|
disabled: plan.disabled,
|
|
1650
|
-
|
|
1655
|
+
ctaDisabled: plan.ctaDisabled,
|
|
1656
|
+
badge: badge2,
|
|
1657
|
+
footer: renderPlanFooter?.(plan)
|
|
1651
1658
|
},
|
|
1652
1659
|
plan.name
|
|
1653
1660
|
);
|
|
@@ -2346,27 +2353,19 @@ function Navbar({
|
|
|
2346
2353
|
})
|
|
2347
2354
|
] }),
|
|
2348
2355
|
/* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
|
|
2349
|
-
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "ghost", size: "icon", className: "justify-self-end md:hidden", children: [
|
|
2356
|
+
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "ghost", size: "icon", className: "col-start-3 justify-self-end md:hidden", children: [
|
|
2350
2357
|
/* @__PURE__ */ jsx(Menu, { className: "size-5" }),
|
|
2351
2358
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Open menu" })
|
|
2352
2359
|
] }) }),
|
|
2353
|
-
/* @__PURE__ */ jsxs(SheetContent, { side: "
|
|
2354
|
-
/* @__PURE__ */
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
/* @__PURE__ */ jsx("span", { children: brand.name })
|
|
2360
|
-
] })
|
|
2361
|
-
}) }),
|
|
2362
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2363
|
-
controls?.map((control, i) => /* @__PURE__ */ jsx(React29.Fragment, { children: control }, i)),
|
|
2364
|
-
/* @__PURE__ */ jsxs(Button$1, { variant: "ghost", size: "icon", onClick: () => setOpen(false), children: [
|
|
2365
|
-
/* @__PURE__ */ jsx(X, { className: "size-4" }),
|
|
2366
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close menu" })
|
|
2367
|
-
] })
|
|
2360
|
+
/* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-72", children: [
|
|
2361
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center pb-4", children: /* @__PURE__ */ jsx("span", { onClick: () => setOpen(false), className: "cursor-pointer", children: renderLink({
|
|
2362
|
+
href: brandHref,
|
|
2363
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 font-semibold", children: [
|
|
2364
|
+
brand.logo,
|
|
2365
|
+
/* @__PURE__ */ jsx("span", { children: brand.name })
|
|
2368
2366
|
] })
|
|
2369
|
-
|
|
2367
|
+
}) }) }),
|
|
2368
|
+
controls?.length ? /* @__PURE__ */ jsx("div", { className: "mb-4 flex w-full items-center justify-between gap-1", children: controls.map((control, i) => /* @__PURE__ */ jsx(React29.Fragment, { children: control }, i)) }) : null,
|
|
2370
2369
|
/* @__PURE__ */ jsx(Separator, {}),
|
|
2371
2370
|
/* @__PURE__ */ jsx("nav", { className: "mt-4 flex flex-col gap-1", children: navLinks.map((link) => /* @__PURE__ */ jsx("span", { onClick: () => setOpen(false), children: renderLink({
|
|
2372
2371
|
href: link.href,
|
|
@@ -3094,6 +3093,8 @@ function FlowConnector({
|
|
|
3094
3093
|
}
|
|
3095
3094
|
function FlowBracket({
|
|
3096
3095
|
anchorTop = 8,
|
|
3096
|
+
anchorTopLeft,
|
|
3097
|
+
anchorTopRight,
|
|
3097
3098
|
anchorBottom = 92,
|
|
3098
3099
|
extent = 22,
|
|
3099
3100
|
arrow = true,
|
|
@@ -3113,30 +3114,32 @@ function FlowBracket({
|
|
|
3113
3114
|
const R = 1e3 + extent;
|
|
3114
3115
|
const cl = colorLeft ?? color;
|
|
3115
3116
|
const cr = colorRight ?? color;
|
|
3116
|
-
const
|
|
3117
|
-
const
|
|
3117
|
+
const aTL = anchorTopLeft ?? anchorTop;
|
|
3118
|
+
const aTR = anchorTopRight ?? anchorTop;
|
|
3119
|
+
const leftD = `M 0,${anchorBottom} L ${L},${anchorBottom} L ${L},${aTL} L 0,${aTL}`;
|
|
3120
|
+
const rightD = reverseRight ? `M 1000,${aTR} L ${R},${aTR} L ${R},${anchorBottom} L 1000,${anchorBottom}` : `M 1000,${anchorBottom} L ${R},${anchorBottom} L ${R},${aTR} L 1000,${aTR}`;
|
|
3118
3121
|
const ep = `${(extent / 10).toFixed(1)}%`;
|
|
3119
3122
|
const dotKeyframes = animate ? `
|
|
3120
3123
|
@keyframes fb-dl{
|
|
3121
3124
|
0%{top:${anchorBottom}%;left:0;opacity:0}
|
|
3122
3125
|
6%{opacity:1}
|
|
3123
3126
|
20%{top:${anchorBottom}%;left:-${ep}}
|
|
3124
|
-
80%{top:${
|
|
3125
|
-
94%{top:${
|
|
3126
|
-
100%{top:${
|
|
3127
|
+
80%{top:${aTL}%;left:-${ep};opacity:1}
|
|
3128
|
+
94%{top:${aTL}%;left:0;opacity:0}
|
|
3129
|
+
100%{top:${aTL}%;left:0;opacity:0}
|
|
3127
3130
|
}
|
|
3128
3131
|
@keyframes fb-dr{
|
|
3129
3132
|
0%{top:${anchorBottom}%;left:100%;opacity:0}
|
|
3130
3133
|
6%{opacity:1}
|
|
3131
3134
|
20%{top:${anchorBottom}%;left:calc(100% + ${ep})}
|
|
3132
|
-
80%{top:${
|
|
3133
|
-
94%{top:${
|
|
3134
|
-
100%{top:${
|
|
3135
|
+
80%{top:${aTR}%;left:calc(100% + ${ep});opacity:1}
|
|
3136
|
+
94%{top:${aTR}%;left:100%;opacity:0}
|
|
3137
|
+
100%{top:${aTR}%;left:100%;opacity:0}
|
|
3135
3138
|
}
|
|
3136
3139
|
@keyframes fb-drr{
|
|
3137
|
-
0%{top:${
|
|
3140
|
+
0%{top:${aTR}%;left:100%;opacity:0}
|
|
3138
3141
|
6%{opacity:1}
|
|
3139
|
-
20%{top:${
|
|
3142
|
+
20%{top:${aTR}%;left:calc(100% + ${ep})}
|
|
3140
3143
|
80%{top:${anchorBottom}%;left:calc(100% + ${ep});opacity:1}
|
|
3141
3144
|
94%{top:${anchorBottom}%;left:100%;opacity:0}
|
|
3142
3145
|
100%{top:${anchorBottom}%;left:100%;opacity:0}
|
|
@@ -3205,7 +3208,7 @@ function FlowBracket({
|
|
|
3205
3208
|
{
|
|
3206
3209
|
"aria-hidden": true,
|
|
3207
3210
|
viewBox: "0 0 10 8",
|
|
3208
|
-
style: { ...arrowBase, top: `${
|
|
3211
|
+
style: { ...arrowBase, top: `${aTL}%`, left: 0 },
|
|
3209
3212
|
children: /* @__PURE__ */ jsx("polyline", { points: "1,1 8,4 1,7", style: { stroke: cl }, ...chevronProps })
|
|
3210
3213
|
}
|
|
3211
3214
|
),
|
|
@@ -3216,7 +3219,7 @@ function FlowBracket({
|
|
|
3216
3219
|
viewBox: "0 0 10 8",
|
|
3217
3220
|
style: {
|
|
3218
3221
|
...arrowBase,
|
|
3219
|
-
top: reverseRight ? `${anchorBottom}%` : `${
|
|
3222
|
+
top: reverseRight ? `${anchorBottom}%` : `${aTR}%`,
|
|
3220
3223
|
left: "100%"
|
|
3221
3224
|
},
|
|
3222
3225
|
children: /* @__PURE__ */ jsx("polyline", { points: "9,1 2,4 9,7", style: { stroke: cr }, ...chevronProps })
|
|
@@ -3454,7 +3457,7 @@ function BrandColorSwitchMinimal() {
|
|
|
3454
3457
|
/* @__PURE__ */ jsx(
|
|
3455
3458
|
"span",
|
|
3456
3459
|
{
|
|
3457
|
-
className:
|
|
3460
|
+
className: `absolute -bottom-0.5 -right-0.5 size-1.5 rounded-full ring-1 ring-background${active === "zinc" ? " dark:ring-white/25" : ""}`,
|
|
3458
3461
|
style: { background: activeHex }
|
|
3459
3462
|
}
|
|
3460
3463
|
)
|
|
@@ -3474,7 +3477,7 @@ function BrandColorSwitchMinimal() {
|
|
|
3474
3477
|
/* @__PURE__ */ jsx(
|
|
3475
3478
|
"span",
|
|
3476
3479
|
{
|
|
3477
|
-
className:
|
|
3480
|
+
className: `flex size-7 items-center justify-center rounded-full ring-offset-background transition-all group-hover:scale-110${color.name === "zinc" ? " border border-transparent dark:border-white/25" : ""}`,
|
|
3478
3481
|
style: {
|
|
3479
3482
|
background: PREVIEW_HEX[color.name],
|
|
3480
3483
|
boxShadow: active === color.name ? `0 0 0 2px var(--background), 0 0 0 4px ${PREVIEW_HEX[color.name]}` : void 0
|