@olwiba/ui 0.2.29 → 0.2.30
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/content/docs/app/error-page.mdx +13 -1
- package/content/docs/marketing/contact-section.mdx +19 -0
- package/content/docs/marketing/cta-section.mdx +17 -0
- package/content/docs/marketing/faq-section.mdx +14 -0
- package/content/docs/marketing/features-section.mdx +14 -0
- package/content/docs/marketing/footer.mdx +15 -0
- package/content/docs/marketing/hero-section.mdx +21 -0
- package/content/docs/marketing/navbar.mdx +14 -0
- package/content/docs/marketing/newsletter-section.mdx +19 -0
- package/content/docs/marketing/post-list.mdx +7 -7
- package/content/docs/marketing/pricing-section.mdx +27 -0
- package/content/docs/marketing/stats-section.mdx +13 -0
- package/content/docs/marketing/team-section.mdx +13 -0
- package/content/docs/marketing/testimonials-section.mdx +13 -0
- package/package.json +7 -5
|
@@ -28,4 +28,16 @@ export const Route = createFileRoute("/404")({
|
|
|
28
28
|
|
|
29
29
|
## API Reference
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Every part of the screen has a default, so `<ErrorPage />` on its own is a complete 404. Pass
|
|
32
|
+
`statusCode`, `title` and `description` to reuse it for 403 or 500, and `links` when you can
|
|
33
|
+
guess where the visitor was actually heading.
|
|
34
|
+
|
|
35
|
+
<APIReference name="ErrorPage" props={[
|
|
36
|
+
{ name: "statusCode", type: "string", default: '"404"', description: "The numerals shown above the title." },
|
|
37
|
+
{ name: "title", type: "string", default: '"Page not found"', description: "Heading." },
|
|
38
|
+
{ name: "description", type: "string", default: "See source", description: "Copy under the heading." },
|
|
39
|
+
{ name: "action", type: "{ label: string; href: string }", default: '{ label: "Take me home", href: "/" }', description: "Primary action." },
|
|
40
|
+
{ name: "backAction", type: "{ label: string; href?: string; onClick?: () => void }", default: '{ label: "Go back" }', description: "Secondary action. Give it an href or an onClick — the default carries neither, so the button renders but does nothing until you do." },
|
|
41
|
+
{ name: "links", type: "ErrorPageLink[]", description: "\"Maybe you were looking for\" links below the actions." },
|
|
42
|
+
{ name: "renderLink", type: "AppShellRenderLink", default: "anchor", description: "Render links through your router instead of a plain anchor." },
|
|
43
|
+
]} />
|
|
@@ -14,3 +14,22 @@ description: Contact form section for marketing pages.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { ContactSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
Every prop has a default, so `<ContactSection />` renders a complete section. The form manages
|
|
21
|
+
its own submitted state — `onSubmit` runs first, and the success panel replaces the form whether
|
|
22
|
+
or not it resolves, so surface delivery failures yourself.
|
|
23
|
+
|
|
24
|
+
<APIReference name="ContactSection" props={[
|
|
25
|
+
{ name: "badge", type: "string", default: '"Contact"', description: "Badge above the title." },
|
|
26
|
+
{ name: "title", type: "string", default: '"Let\'s talk"', description: "Section heading." },
|
|
27
|
+
{ name: "description", type: "string", default: "See source", description: "Copy under the heading." },
|
|
28
|
+
{ name: "contactInfo", type: "ContactInfoItem[]", description: "Address, phone and similar, shown as a row above the form. Each item takes a `label`, a `value` and an optional Lucide `icon`." },
|
|
29
|
+
{ name: "privacyHref", type: "string", description: "Links the privacy note under the submit button. Omit it and no note is shown." },
|
|
30
|
+
{ name: "successTitle", type: "string", default: '"Message sent"', description: "Heading of the panel that replaces the form." },
|
|
31
|
+
{ name: "successDescription", type: "string", default: "See source", description: "Copy in the success panel." },
|
|
32
|
+
{ name: "sendAnotherLabel", type: "string", default: '"Send another"', description: "Label of the button that restores the form." },
|
|
33
|
+
{ name: "onSubmit", type: "(event: React.FormEvent<HTMLFormElement>) => void | Promise<void>", description: "Awaited before the success panel appears. The section never posts anywhere on its own." },
|
|
34
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
35
|
+
]} />
|
|
@@ -29,3 +29,20 @@ import { CtaSection } from "@olwiba/ui";
|
|
|
29
29
|
icon={<Rocket className="size-72" strokeWidth={0.75} />}
|
|
30
30
|
/>
|
|
31
31
|
```
|
|
32
|
+
|
|
33
|
+
## API Reference
|
|
34
|
+
|
|
35
|
+
`icon` and the single pill CTA only apply to `variant="showcase"`; `secondaryCta` is dropped
|
|
36
|
+
there, so put the one action that matters in `primaryCta`.
|
|
37
|
+
|
|
38
|
+
<APIReference name="CtaSection" props={[
|
|
39
|
+
{ name: "heading", type: "string", description: "The headline. Required." },
|
|
40
|
+
{ name: "primaryCta", type: "{ label: string; href: string }", description: "Primary action. Required." },
|
|
41
|
+
{ name: "description", type: "string", description: "Copy under the headline." },
|
|
42
|
+
{ name: "secondaryCta", type: "{ label: string; href: string }", description: "Secondary action. Default variant only." },
|
|
43
|
+
{ name: "footnote", type: "string", description: "Small print under the buttons." },
|
|
44
|
+
{ name: "variant", type: '"default" | "showcase"', default: '"default"', description: "Badge icon and radial glow, or a large watermark icon with a scroll reveal." },
|
|
45
|
+
{ name: "icon", type: "React.ReactNode", default: "<Rocket />", description: "Watermark icon behind the content. Showcase only." },
|
|
46
|
+
{ name: "renderLink", type: "AppShellRenderLink", default: "anchor", description: "Render CTAs through your router instead of a plain anchor." },
|
|
47
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
48
|
+
]} />
|
|
@@ -14,3 +14,17 @@ description: Accordion FAQ section for marketing pages.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { FaqSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
`items` is the only prop without a default. Answers are rendered as plain text inside a
|
|
21
|
+
single-open [Accordion](/docs/components/accordion), so keep them to a paragraph and link out
|
|
22
|
+
for anything longer.
|
|
23
|
+
|
|
24
|
+
<APIReference name="FaqSection" props={[
|
|
25
|
+
{ name: "items", type: "Array<{ question: string; answer: string }>", description: "The questions. Required." },
|
|
26
|
+
{ name: "title", type: "string", default: '"Frequently asked questions"', description: "Section heading." },
|
|
27
|
+
{ name: "description", type: "string", default: "See source", description: "Copy under the heading." },
|
|
28
|
+
{ name: "badge", type: "string", default: '"FAQ"', description: "Badge above the title." },
|
|
29
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
30
|
+
]} />
|
|
@@ -21,3 +21,17 @@ import { FeaturesSection } from "@olwiba/ui";
|
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
`layout="carousel"` renders the same cards in a scroll-snap [Carousel](/docs/mechanics/carousel) with prev/next controls. To carousel your own content outside a section, use the `Carousel` mechanic directly.
|
|
24
|
+
|
|
25
|
+
## API Reference
|
|
26
|
+
|
|
27
|
+
`icon` on each feature is a Lucide component, passed uninstantiated — `{ icon: Zap }`, not
|
|
28
|
+
`{ icon: <Zap /> }`.
|
|
29
|
+
|
|
30
|
+
<APIReference name="FeaturesSection" props={[
|
|
31
|
+
{ name: "features", type: "Array<{ icon: LucideIcon; title: string; description: string; href?: string }>", description: "The cards. A feature with an `href` becomes a link. Required." },
|
|
32
|
+
{ name: "title", type: "string", default: '"Everything you need to ship fast"', description: "Section heading." },
|
|
33
|
+
{ name: "description", type: "string", default: "See source", description: "Copy under the heading." },
|
|
34
|
+
{ name: "badge", type: "string", default: '"Features"', description: "Badge above the title." },
|
|
35
|
+
{ name: "layout", type: '"grid" | "carousel"', default: '"grid"', description: "How the cards are arranged." },
|
|
36
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
37
|
+
]} />
|
|
@@ -14,3 +14,18 @@ description: Site footer with links and branding.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { Footer } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
`brand` is the only required prop. `status.label` is a `ReactNode` rather than a string on
|
|
21
|
+
purpose: a real status pill usually carries per-service detail in a tooltip, and typing it as a
|
|
22
|
+
string forced callers to smuggle that through a cast.
|
|
23
|
+
|
|
24
|
+
<APIReference name="Footer" props={[
|
|
25
|
+
{ name: "brand", type: "{ name: string; logo?: ReactNode; href?: string }", description: "Wordmark, optional mark, and where it links. Required." },
|
|
26
|
+
{ name: "navLinks", type: "Array<{ label: string; href: string }>", description: "The link row." },
|
|
27
|
+
{ name: "socialLinks", type: "Array<{ label: string; href: string; icon: ReactNode }>", description: "Icon links. `label` is the accessible name." },
|
|
28
|
+
{ name: "legal", type: "string", description: "Copyright line." },
|
|
29
|
+
{ name: "status", type: "{ label: ReactNode; operational?: boolean }", description: "Live status pill. `operational` picks the dot colour." },
|
|
30
|
+
{ name: "renderLink", type: "AppShellRenderLink", default: "anchor", description: "Render links through your router instead of a plain anchor." },
|
|
31
|
+
]} />
|
|
@@ -14,3 +14,24 @@ description: Above-the-fold hero section with headline, supporting copy, and CTA
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { HeroSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
`heading` and `description` are required; everything else is opt-in. `primarySlot` replaces the
|
|
21
|
+
primary button entirely — reach for it when the product itself can start in the hero rather than
|
|
22
|
+
one page later.
|
|
23
|
+
|
|
24
|
+
<APIReference name="HeroSection" props={[
|
|
25
|
+
{ name: "heading", type: "string", description: "The headline. Required." },
|
|
26
|
+
{ name: "description", type: "string", description: "Supporting copy under the headline. Required." },
|
|
27
|
+
{ name: "badge", type: "string", description: "Small badge above the headline." },
|
|
28
|
+
{ name: "primaryCta", type: "{ label: string; href: string }", description: "Primary button. Ignored when `primarySlot` is given." },
|
|
29
|
+
{ name: "secondaryCta", type: "{ label: string; href: string }", description: "Secondary button, and it survives `primarySlot`." },
|
|
30
|
+
{ name: "primarySlot", type: "React.ReactNode", description: "Your own control in place of the primary button — a search field, an email capture. Full-width above the secondary CTA on small screens." },
|
|
31
|
+
{ name: "heroImage", type: "React.ReactNode", description: "What fills the media column." },
|
|
32
|
+
{ name: "media", type: '"image" | "phone" | "none"', default: '"image"', description: "How the media column is framed, or whether there is one." },
|
|
33
|
+
{ name: "phoneSize", type: '"sm" | "md" | "lg"', default: '"lg"', description: 'Phone frame size when media is "phone".' },
|
|
34
|
+
{ name: "avatarUrls", type: "string[]", description: "Stacked avatars beside the social proof line." },
|
|
35
|
+
{ name: "socialProofText", type: "string", description: "The line beside the avatars." },
|
|
36
|
+
{ name: "renderLink", type: "AppShellRenderLink", default: "anchor", description: "Render CTAs through your router instead of a plain anchor." },
|
|
37
|
+
]} />
|
|
@@ -14,3 +14,17 @@ description: Responsive top navigation bar for marketing sites.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { Navbar } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
`controls` sits between the nav and the CTAs and is meant for icon buttons —
|
|
21
|
+
`ModeSwitchMinimal`, `ThemeSwitchMinimal` and the like. Anything with a label belongs in
|
|
22
|
+
`navLinks` or `cta` instead.
|
|
23
|
+
|
|
24
|
+
<APIReference name="Navbar" props={[
|
|
25
|
+
{ name: "brand", type: "{ name: string; logo?: React.ReactNode; href?: string }", description: "Wordmark, optional mark, and where it links. Required." },
|
|
26
|
+
{ name: "navLinks", type: "Array<{ label: string; href: string }>", description: "The links. Required." },
|
|
27
|
+
{ name: "cta", type: "{ primary?: { label: string; href: string }; secondary?: { label: string; href: string } }", description: "Buttons at the right end." },
|
|
28
|
+
{ name: "controls", type: "React.ReactNode[]", description: "Icon buttons rendered right of the nav and left of the CTAs." },
|
|
29
|
+
{ name: "renderLink", type: "AppShellRenderLink", default: "anchor", description: "Render links through your router instead of a plain anchor." },
|
|
30
|
+
]} />
|
|
@@ -14,3 +14,22 @@ description: Email capture form section for marketing pages.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { NewsletterSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
`privacyHref` defaults to `"#"`, which is a link that goes nowhere. Point it at your real policy
|
|
21
|
+
before this section ships.
|
|
22
|
+
|
|
23
|
+
<APIReference name="NewsletterSection" props={[
|
|
24
|
+
{ name: "onSubscribe", type: "(email: string) => void | Promise<void>", description: "Awaited before the success panel appears. The section never posts anywhere on its own." },
|
|
25
|
+
{ name: "badge", type: "string", default: '"Newsletter"', description: "Badge above the title." },
|
|
26
|
+
{ name: "title", type: "string", default: '"Stay in the loop"', description: "Section heading." },
|
|
27
|
+
{ name: "description", type: "string", default: "See source", description: "Copy under the heading." },
|
|
28
|
+
{ name: "placeholder", type: "string", default: '"you@company.com"', description: "Email field placeholder." },
|
|
29
|
+
{ name: "submitLabel", type: "string", default: '"Subscribe"', description: "Submit button label." },
|
|
30
|
+
{ name: "privacyHref", type: "string", default: '"#"', description: "Target of the privacy link under the field." },
|
|
31
|
+
{ name: "privacyLabel", type: "string", default: '"Privacy Policy"', description: "Text of that link." },
|
|
32
|
+
{ name: "successTitle", type: "string", default: '"You\'re on the list."', description: "Heading of the panel that replaces the form." },
|
|
33
|
+
{ name: "successDescription", type: "string", default: '"We\'ll be in touch soon."', description: "Copy in the success panel." },
|
|
34
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
35
|
+
]} />
|
|
@@ -23,10 +23,10 @@ Pass `columns={2}` or `columns={3}` when the surrounding page needs an explicit
|
|
|
23
23
|
|
|
24
24
|
## API Reference
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
<APIReference name="PostList" props={[
|
|
27
|
+
{ name: "posts", type: "PostCardProps[]", description: "Posts rendered as PostCard items. Required." },
|
|
28
|
+
{ name: "renderLink", type: "AppShellRenderLink", description: "Render links through your router instead of a plain anchor." },
|
|
29
|
+
{ name: "emptyMessage", type: "string", default: '"No posts published yet."', description: "Shown instead of the grid when `posts` is empty." },
|
|
30
|
+
{ name: "columns", type: "2 | 3", default: "automatic", description: "Maximum columns at the widest breakpoint. Setting it disables the automatic short-list balancing." },
|
|
31
|
+
{ name: "className", type: "string", description: "Additional classes on the grid container." },
|
|
32
|
+
]} />
|
|
@@ -14,3 +14,30 @@ description: Pricing cards with plan details and feature comparison.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { PricingSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
The cadence toggle's state lives inside the section, so `onSelectPlan` is how you find out which
|
|
21
|
+
billing period was selected when a CTA is pressed. Without it the CTAs are inert.
|
|
22
|
+
|
|
23
|
+
<APIReference name="PricingSection" props={[
|
|
24
|
+
{ name: "plans", type: "PricingPlan[]", description: "The tiers. Required." },
|
|
25
|
+
{ name: "onSelectPlan", type: "(plan: PricingPlan, cadence?: string) => void", description: "Called when a plan's CTA is pressed, with the cadence currently selected." },
|
|
26
|
+
{ name: "title", type: "string", default: '"Simple, transparent pricing"', description: "Section heading." },
|
|
27
|
+
{ name: "description", type: "string", default: '"Start for free. Scale as you grow. No hidden fees."', description: "Copy under the heading." },
|
|
28
|
+
{ name: "badge", type: "React.ReactNode", default: '"Pricing"', description: "Badge above the title." },
|
|
29
|
+
{ name: "mode", type: '"subscription" | "one-time"', default: '"subscription"', description: "Whether prices are recurring. Not the surface treatment — see `surface`." },
|
|
30
|
+
{ name: "cadences", type: "PricingCadence[]", default: "Monthly / Annual", description: "Billing periods sold. One entry renders no toggle; two or more render a tab each." },
|
|
31
|
+
{ name: "defaultCadence", type: "string", default: "first cadence", description: "Which cadence opens selected." },
|
|
32
|
+
{ name: "currency", type: "string", default: '"$"', description: "Symbol prepended to computed prices. Ignored by plans with `priceDisplay`." },
|
|
33
|
+
{ name: "saveBadge", type: "string", default: '"Save 34%"', description: "Fallback savings badge when no `periodsPerYear` is given." },
|
|
34
|
+
{ name: "highlightedBadgeLabel", type: "string", default: '"Founding member"', description: "Badge on highlighted plans with no active countdown. Pass an empty string for none." },
|
|
35
|
+
{ name: "foundingDeadline", type: "string", description: "Runs a countdown on the highlighted plan until this date." },
|
|
36
|
+
{ name: "footnote", type: "string", description: "Small print below the cards." },
|
|
37
|
+
{ name: "isAuthenticated", type: "boolean", description: "Lets plan CTAs read as upgrade rather than sign-up." },
|
|
38
|
+
{ name: "pendingPlanName", type: "string", description: "Marks one plan busy while its checkout is created." },
|
|
39
|
+
{ name: "renderPlanFooter", type: "(plan: PricingPlan) => React.ReactNode", description: "Rendered below each plan's CTA." },
|
|
40
|
+
{ name: "priceEffect", type: 'PricingCardProps["priceEffect"]', default: "UI mode decides", description: 'How a price transitions when the cadence changes. Pass "roll" for an odometer.' },
|
|
41
|
+
{ name: "renderLink", type: "AppShellRenderLink", default: "anchor", description: "Render CTAs through your router instead of a plain anchor." },
|
|
42
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
43
|
+
]} />
|
|
@@ -14,3 +14,16 @@ description: Key metrics display section for marketing pages.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { StatsSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
`value` is a string rather than a number so the section never has to guess at formatting —
|
|
21
|
+
`"99.9%"`, `"12k"` and `"<50ms"` all render as written.
|
|
22
|
+
|
|
23
|
+
<APIReference name="StatsSection" props={[
|
|
24
|
+
{ name: "stats", type: "Array<{ value: string; label: string; description?: string }>", description: "The figures. Required." },
|
|
25
|
+
{ name: "title", type: "string", default: '"Built for scale, used in production"', description: "Section heading." },
|
|
26
|
+
{ name: "description", type: "string", description: "Copy under the heading. No default — omit it and nothing renders there." },
|
|
27
|
+
{ name: "badge", type: "string", default: '"By the numbers"', description: "Badge above the title." },
|
|
28
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
29
|
+
]} />
|
|
@@ -14,3 +14,16 @@ description: Team member grid for about and marketing pages.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { TeamSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
`members` has a placeholder default so the section renders before you have the copy. Replace it
|
|
21
|
+
before shipping — the built-in people are not yours.
|
|
22
|
+
|
|
23
|
+
<APIReference name="TeamSection" props={[
|
|
24
|
+
{ name: "members", type: "TeamMember[]", default: "placeholder team", description: "Each takes `name`, `role`, `bio`, `initials`, an optional `avatar` URL and optional `social` handles." },
|
|
25
|
+
{ name: "badge", type: "string", default: '"Team"', description: "Badge above the title." },
|
|
26
|
+
{ name: "title", type: "string", default: '"The people behind Olwiba"', description: "Section heading." },
|
|
27
|
+
{ name: "description", type: "string", default: "See source", description: "Copy under the heading." },
|
|
28
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
29
|
+
]} />
|
|
@@ -14,3 +14,16 @@ description: Customer quote grid for marketing pages.
|
|
|
14
14
|
```tsx
|
|
15
15
|
import { TestimonialsSection } from "@olwiba/ui";
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Reference
|
|
19
|
+
|
|
20
|
+
Give each testimonial either an `avatar` or `initials` — with neither, the card falls back to an
|
|
21
|
+
empty circle.
|
|
22
|
+
|
|
23
|
+
<APIReference name="TestimonialsSection" props={[
|
|
24
|
+
{ name: "testimonials", type: "Array<{ quote: string; name: string; role: string; company?: string; avatar?: string; initials?: string; rating?: number }>", description: "The quotes. Required." },
|
|
25
|
+
{ name: "title", type: "string", default: '"Trusted by teams shipping real products"', description: "Section heading." },
|
|
26
|
+
{ name: "description", type: "string", default: "See source", description: "Copy under the heading." },
|
|
27
|
+
{ name: "badge", type: "string", default: '"Testimonials"', description: "Badge above the title." },
|
|
28
|
+
{ name: "surface", type: '"card" | "soft" | "plain"', default: '"card"', description: "How the section sits on the page. Falls back to MarketingSurfaceProvider." },
|
|
29
|
+
]} />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olwiba/ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.30",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
"start": "bun run server.ts",
|
|
43
43
|
"types:check": "fumadocs-mdx && tsc --noEmit",
|
|
44
44
|
"iso:generate": "bun scripts/generate-iso-previews.ts",
|
|
45
|
-
"email:generate": "bun scripts/generate-email-previews.ts"
|
|
45
|
+
"email:generate": "bun scripts/generate-email-previews.ts",
|
|
46
|
+
"env:check": "dx env-check",
|
|
47
|
+
"docs:check": "dx docs-check"
|
|
46
48
|
},
|
|
47
49
|
"dependencies": {
|
|
48
50
|
"@dnd-kit/core": "^6.3.1",
|
|
@@ -70,9 +72,9 @@
|
|
|
70
72
|
},
|
|
71
73
|
"devDependencies": {
|
|
72
74
|
"@content-collections/mdx": "^0.2.2",
|
|
73
|
-
"@olwiba/cn": "0.1.
|
|
74
|
-
"@olwiba/docs": "0.1.
|
|
75
|
-
"@olwiba/dx": "0.0.
|
|
75
|
+
"@olwiba/cn": "0.1.40",
|
|
76
|
+
"@olwiba/docs": "0.1.46",
|
|
77
|
+
"@olwiba/dx": "0.0.28",
|
|
76
78
|
"@react-email/render": "^2.1.0",
|
|
77
79
|
"@tailwindcss/vite": "^4.1.18",
|
|
78
80
|
"@tanstack/react-router": "1.154.8",
|