Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"start": "next start"
},
"dependencies": {
"@radix-ui/react-accordion": "^1.2.2",
"@theguild/components": "^7.6.0",
"next": "^15.0.0",
"next-sitemap": "^4.2.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use client';

import { useEffect } from 'react';

export function AttachPageFAQSchema() {
useEffect(() => {
const html = document.querySelector('html');

if (!html) {
// This should never happen
return;
}

const path = window.location.pathname.replace('/graphql/hive', '/');

if (!html.hasAttribute('itemscope')) {
html.setAttribute('itemscope', '');
html.setAttribute('itemtype', 'https://schema.org/FAQPage');

return () => {
html.removeAttribute('itemscope');
html.removeAttribute('itemtype');
};
}
}, []);

return null;
}
111 changes: 111 additions & 0 deletions website/src/components/frequently-asked-questions/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// TODO: Remove this module and use FrequentlyAskedQuestions from @theguild/components v8 when it's
// released and Mesh is migrated to Nextra 4.

import { Children, ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react';
import * as RadixAccordion from '@radix-ui/react-accordion';
import { Anchor, CaretSlimIcon, cn, Heading } from '@theguild/components';
import { AttachPageFAQSchema } from './attach-page-faq-schema';
import MeshFAQ from './mesh-faq.mdx';

const a = (props: ComponentPropsWithoutRef<'a'>) => (
<Anchor
className="hive-focus rounded underline hover:text-blue-700"
{...props}
href={props.href!}
>
{props.children!}
</Anchor>
);

const h2 = (props: ComponentPropsWithoutRef<'h2'>) => (
<Heading as="h2" size="md" className="basis-1/2" {...props} />
);

const UnwrapChild = (props: { children?: ReactNode }) => props.children as unknown as ReactElement;

const Accordion = (props: ComponentPropsWithoutRef<'ul'>) => (
<RadixAccordion.Root asChild type="single" collapsible>
<ul className="divide-beige-400 basis-1/2 divide-y max-xl:grow" {...props} />
</RadixAccordion.Root>
);

const AccordionItem = (props: ComponentPropsWithoutRef<'li'>) => {
const texts = Children.toArray(props.children).filter(child => child !== '\n');

if (texts.length === 0) {
return null;
}

if (texts.length < 2) {
console.error(texts);
throw new Error(`Expected a question and an answer, got ${texts.length} items`);
}

const [first, ...answers] = texts;

const question =
typeof first === 'string'
? first
: typeof first === 'object' && 'type' in first
? (first as ReactElement<{ children?: ReactNode }>).props.children?.toString()
: null;

if (!question) return null;

return (
<RadixAccordion.Item
asChild
value={question}
className="rdx-state-open:pb-4 relative pb-2 focus-within:z-10"
itemScope
itemProp="mainEntity"
itemType="https://schema.org/Question"
>
<li>
<RadixAccordion.Header>
<RadixAccordion.Trigger className="hive-focus hover:bg-beige-100/80 -mx-2 my-1 flex w-[calc(100%+1rem)] items-center justify-between rounded-xl bg-white px-2 py-3 text-left font-medium transition-colors duration-[.8s] md:my-2 md:py-4">
<span itemProp="name">{question}</span>
<CaretSlimIcon className="size-5 [[data-state='open']_&]:[transform:rotateX(180deg)]" />
</RadixAccordion.Trigger>
</RadixAccordion.Header>
<RadixAccordion.Content
forceMount
className="overflow-hidden bg-white text-green-800 data-[state=closed]:hidden"
itemScope
itemProp="acceptedAnswer"
itemType="https://schema.org/Answer"
>
<div itemProp="text" className="space-y-2">
{answers.map((answer, i) => (
<p key={i}>{answer}</p>
))}
</div>
</RadixAccordion.Content>
</li>
</RadixAccordion.Item>
);
};

export function FrequentlyAskedQuestions({ className }: { className?: string }) {
return (
<>
<AttachPageFAQSchema />
<section
className={cn(
className,
'text-green-1000 flex flex-col gap-x-6 gap-y-2 px-4 py-6 md:flex-row md:px-10 lg:gap-x-24 lg:px-[120px] lg:py-24',
)}
>
<MeshFAQ
components={{
a,
h2,
p: UnwrapChild,
ul: Accordion,
li: AccordionItem,
}}
/>
</section>
</>
);
}
11 changes: 11 additions & 0 deletions website/src/components/frequently-asked-questions/mesh-faq.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Frequently Asked Questions

- What is Mesh?

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua.

- How do I use it?

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua.
3 changes: 2 additions & 1 deletion website/src/components/index-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ComparisonTable } from './comparison-table';
import { DatasourcesIllustration } from './datasources-illustration';
import { DatasourcesListSection } from './datasources-list-section';
import { ExamplesSection } from './examples-section';
import { FrequentlyAskedQuestions } from './frequently-asked-questions';
import { InfoCardsSection } from './info-cards-section';
import { LandingPageContainer } from './landing-page-container';
import { ManipulateDataSection } from './manipulate-data-section';
Expand All @@ -24,7 +25,7 @@ export function IndexPage(): ReactElement {
<RunAnywhereSection className="mx-4 mt-6 md:mx-6" />
<CapabilitiesSection className="mx-4 mt-6 md:mx-6" />
<ToolsAndLibrariesCards className="mx-4 md:mx-6" />
{/* TODO: Frequently Asked Questions requires a version bump of @theguild/components */}
<FrequentlyAskedQuestions className="mx-4 mt-6 md:mx-6" />
</LandingPageContainer>
);
}
70 changes: 55 additions & 15 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10913,6 +10913,59 @@ __metadata:
languageName: node
linkType: hard

"@radix-ui/react-accordion@npm:^1.2.2":
version: 1.2.2
resolution: "@radix-ui/react-accordion@npm:1.2.2"
dependencies:
"@radix-ui/primitive": "npm:1.1.1"
"@radix-ui/react-collapsible": "npm:1.1.2"
"@radix-ui/react-collection": "npm:1.1.1"
"@radix-ui/react-compose-refs": "npm:1.1.1"
"@radix-ui/react-context": "npm:1.1.1"
"@radix-ui/react-direction": "npm:1.1.0"
"@radix-ui/react-id": "npm:1.1.0"
"@radix-ui/react-primitive": "npm:2.0.1"
"@radix-ui/react-use-controllable-state": "npm:1.1.0"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/2279c24de3296714ad14e0b83e7ea55f1b0d1585650b48ddb9295a44e6f0ab4e860526e9263c8f18cbdfa702648644d1bfa50f18c22e6f9de303b4b19ebef63a
languageName: node
linkType: hard

"@radix-ui/react-collapsible@npm:1.1.2":
version: 1.1.2
resolution: "@radix-ui/react-collapsible@npm:1.1.2"
dependencies:
"@radix-ui/primitive": "npm:1.1.1"
"@radix-ui/react-compose-refs": "npm:1.1.1"
"@radix-ui/react-context": "npm:1.1.1"
"@radix-ui/react-id": "npm:1.1.0"
"@radix-ui/react-presence": "npm:1.1.2"
"@radix-ui/react-primitive": "npm:2.0.1"
"@radix-ui/react-use-controllable-state": "npm:1.1.0"
"@radix-ui/react-use-layout-effect": "npm:1.1.0"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/8a725539c0c259ea53a0e35d4ddd3acca42cab5113fd537758450ad1e76f0b757423f18aca29364f963bef4f0624d57feb32bf9d12a3ea6b2c084b523ba65205
languageName: node
linkType: hard

"@radix-ui/react-collection@npm:1.1.1":
version: 1.1.1
resolution: "@radix-ui/react-collection@npm:1.1.1"
Expand Down Expand Up @@ -16021,21 +16074,7 @@ __metadata:
languageName: node
linkType: hard

"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.19.1, browserslist@npm:^4.21.4, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0":
version: 4.24.4
resolution: "browserslist@npm:4.24.4"
dependencies:
caniuse-lite: "npm:^1.0.30001688"
electron-to-chromium: "npm:^1.5.73"
node-releases: "npm:^2.0.19"
update-browserslist-db: "npm:^1.1.1"
bin:
browserslist: cli.js
checksum: 10c0/db7ebc1733cf471e0b490b4f47e3e2ea2947ce417192c9246644e92c667dd56a71406cc58f62ca7587caf828364892e9952904a02b7aead752bc65b62a37cfe9
languageName: node
linkType: hard

"browserslist@npm:^4.24.2":
"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.19.1, browserslist@npm:^4.21.4, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0, browserslist@npm:^4.24.2":
version: 4.24.3
resolution: "browserslist@npm:4.24.3"
dependencies:
Expand Down Expand Up @@ -36935,6 +36974,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "website@workspace:website"
dependencies:
"@radix-ui/react-accordion": "npm:^1.2.2"
"@theguild/components": "npm:^7.6.0"
"@theguild/tailwind-config": "npm:0.6.2"
"@types/node": "npm:22.10.6"
Expand Down
Loading