A procurement FAQ grouping security controls into hairline rows that pair each question with a tone-coded yes, partial, or not-yet chip and the detail behind it, closing on a security pack request.
A procurement FAQ grouping security controls into hairline rows that pair each question with a tone-coded yes, partial or not-yet chip and the detail behind it, closing on a security pack request.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/faq90?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/faq90?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/faq90.tsx plus the badge23 and button21 components it uses for the eyebrow and the pack actions.
The installed file exports faq90Demo alongside the block: the exact props behind the preview above. Spread it to get a working questionnaire in one line.
import { Faq90, faq90Demo } from "@/components/beste/block/faq90";
export default function SecurityPage() {
return <Faq90 {...faq90Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Faq90 } from "@/components/beste/block/faq90";
export default function SecurityPage() {
return (
<Faq90
badge={{ label: "For procurement" }}
heading="The security questionnaire, answered before you send it"
description="Honest answers, including the two that are still a no."
answerLabels={{ yes: "Yes", partial: "Partial", no: "Not yet" }}
groups={[
{
label: "Data and residency",
controls: [
{
question: "Is data encrypted at rest and in transit?",
answer: "yes",
detail: "AES-256 at rest, TLS 1.3 in transit, keys rotated quarterly.",
},
],
},
{
label: "Assurance",
controls: [
{
question: "Do you hold ISO 27001?",
answer: "partial",
detail: "Audit is underway with certification expected in the fourth quarter.",
},
{
question: "Do you offer an on-premise deployment?",
answer: "no",
detail: "No, and we do not intend to.",
},
],
},
]}
packTitle="The rest of the pack"
packBody="Architecture diagrams, the sub-processor register, and the DPA."
buttons={[
{ label: "Request the security pack", href: "/security/pack" },
{ label: "Read the trust page", href: "/trust" },
]}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow above the hairline rule, rendered through Badge23 |
heading | string | – | Section heading in the left column of the header |
description | string | – | Supporting paragraph, right-aligned from md up |
answerLabels | Record<Answer, string> | – | The word shown on each answer chip |
groups | ControlGroup[] | [] | Control groups, each a labelled set of rows |
packTitle | string | – | Heading in the closing pack panel |
packBody | string | – | Paragraph in the pack panel |
buttons | ActionLink[] | [] | Pack actions, first solid and the rest outlined |
className | string | – | Extra classes for the outer section |
type Answer = "yes" | "partial" | "no";
type ActionLink = {
label: string;
href: string;
};
type Control = {
question: string;
answer: Answer;
detail: string;
};
type ControlGroup = {
label: string;
controls: Control[];
};answer is a three-value union, not a boolean, which is the point of the block: procurement questions rarely have a clean yes or no, and the middle state has somewhere honest to go.answerStyles table (emerald, amber, muted) plus a word, so the state never depends on hue alone.answerLabels falls back to the raw key when a label is missing, so an incomplete record degrades to "partial" rather than rendering blank.detail is required on every control. A chip on its own answers nothing, so the block forces the caveat to travel with the answer.md: question, a fixed 7rem answer column, then the detail. The chip is w-fit, so it hugs its label rather than filling that track.md the row stacks into question, chip and detail, keeping the same reading order.mb-10 with last:mb-0, and each control carries border-t, so rules appear between rows and above the first row of each group.faq84
A compact FAQ with nothing hidden behind a click: three labelled groups of question and answer pairs set as two-column hairline rows, closing on a link to longer reading.
faq81
FAQ split into two labelled groups, each an independent accordion of ruled questions, so a long list stays scannable by topic; closed by a response-time note beside an outline pill CTA.
faq68
Two-column FAQ section with a badge, heading, and description on the left, and a stacked list of numbered question cards on the right. Each card opens to reveal a plain answer block below it with no separator line.
faq12
FAQs organized into titled sections with accordions underneath. Excellent for presenting related questions grouped by topic.