mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
The six pages that opened on components/products/Lede drew a centred heading over a glow, short of the window and narrower than the bar. Lede now hands its title, paragraph, badge, actions and facts to the shared fold, and each page walks its product beside the words: an order from variant to return, a document from upload to certificate, a shared link from folder to revoked access, a round from share classes to the waterfall. /iam's and /s3's fact lists are the walk itself, with the API reference, the discovery document and the source beside the title (each answers 200).
64 lines
2.0 KiB
TypeScript
64 lines
2.0 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
import type { LucideIcon } from 'lucide-react'
|
|
import { ArrowRight } from 'lucide-react'
|
|
import { Action } from '@hanzo/ui/marketing'
|
|
import { T } from '@hanzo/i18n/react'
|
|
import type { CTA } from '@/components/product/ProductLanding'
|
|
import { Fold } from '@/components/marketing/fold'
|
|
|
|
/**
|
|
* A product stated in one heading and one paragraph: the first screen six pages
|
|
* open on (/commerce, /sign, /dataroom, /captable, /iam, /s3). It is a caller
|
|
* of `components/marketing/fold`, so it fills the window, keeps the bar's
|
|
* measure and stands the product's `preview` beside the words from 1024px.
|
|
*
|
|
* The title is a node rather than a string because a caller may count
|
|
* something in its own heading. `badge`, a string `title`, each action's label
|
|
* and each fact are drawn through the catalog: a caller marks the literal
|
|
* `phrase('…')` where it writes it. The paragraph is the caller's markup.
|
|
*/
|
|
export function Lede({
|
|
title,
|
|
badge,
|
|
badgeIcon: Badge,
|
|
actions,
|
|
facts,
|
|
preview,
|
|
children,
|
|
}: {
|
|
title: ReactNode
|
|
badge?: string
|
|
badgeIcon?: LucideIcon
|
|
actions?: CTA[]
|
|
/** What the product does, one fact a line, under the paragraph. */
|
|
facts?: readonly string[]
|
|
/** The product at work, beside the words. */
|
|
preview?: ReactNode
|
|
children: ReactNode
|
|
}) {
|
|
return (
|
|
<Fold
|
|
label={badge}
|
|
mark={Badge ? <Badge width={14} height={14} color="currentColor" aria-hidden /> : undefined}
|
|
title={title}
|
|
lede={children}
|
|
points={facts ? [...facts] : undefined}
|
|
preview={preview}
|
|
actions={
|
|
actions && actions.length > 0
|
|
? actions.map((a, i) => {
|
|
const Icon = a.icon ?? (i === 0 ? ArrowRight : undefined)
|
|
return (
|
|
<Action key={a.label} href={a.href} fill={i === 0}>
|
|
<T>{a.label}</T> {Icon && <Icon width={16} height={16} data-i18n-mirror={a.icon ? undefined : ''} />}
|
|
</Action>
|
|
)
|
|
})
|
|
: undefined
|
|
}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export default Lede
|