mirror of
https://github.com/hanzoai/community.git
synced 2026-10-30 14:39:19 +00:00
The page mounts the docs.hanzo.ai wiring: @hanzo/event sends the pageview to api.hanzo.ai/v1/event with project hanzo-community's publishable key, startTags loads the site's GA4 and Meta tags from cloud once the visitor consents, and @hanzo/ui/consent is the banner. @hanzo/ui 8.29.12 is the first version this repo takes that has the banner. It registers its gui config, so stacks type against the v5 shorthands, and the page moves to them. Its stylesheet is imported in the layout; without it the export rendered unstyled. Overrides keep one gui and one event client in the tree. hanzo.yml and the hanzoai/ci caller type-check, build out/ and publish it as Sites project hanzo-community on every push to main.
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
'use client'
|
|
|
|
import type { ComponentProps, ReactNode } from 'react'
|
|
import { Anchor, XStack } from '@hanzo/ui'
|
|
|
|
/**
|
|
* Bar — the rule-lined row at the top and the bottom of the page.
|
|
*
|
|
* Header and footer scored .42 against each other on class vocabulary, the
|
|
* highest pair on the page after the two cards, and every token in the overlap
|
|
* spells the same thing: a full-bleed strip with a hairline on one edge, and
|
|
* inside it a centred measure holding its ends apart. The strip has to be the
|
|
* OUTER box — put the measure's width on it instead and the hairline stops short
|
|
* of the window.
|
|
*/
|
|
export const Bar = ({
|
|
top,
|
|
paddingVertical,
|
|
stack,
|
|
children,
|
|
}: {
|
|
/** Which edge carries the hairline — and so which end of the page this is. */
|
|
top?: boolean
|
|
paddingVertical: number
|
|
/** Stack the ends until there is room to sit them side by side. */
|
|
stack?: boolean
|
|
children: ReactNode
|
|
}) => (
|
|
<XStack
|
|
render={top ? 'header' : 'footer'}
|
|
width="100%"
|
|
px={24}
|
|
py={paddingVertical}
|
|
justify="center"
|
|
borderColor="$edge"
|
|
{...(top ? { borderBottomWidth: 1 } : { borderTopWidth: 1 })}
|
|
>
|
|
<XStack
|
|
width="100%"
|
|
maxW={1024}
|
|
gap={16}
|
|
items="center"
|
|
justify="space-between"
|
|
flexDirection={stack ? 'column' : 'row'}
|
|
// The ends wrap onto a second line rather than pushing a scrollbar onto
|
|
// the page: at 390px the wordmark and the nav want 357px of a 342px
|
|
// measure, and a bar that cannot wrap makes the whole document scroll
|
|
// sideways. Above that there is room and nothing wraps.
|
|
flexWrap="wrap"
|
|
$sm={{ flexDirection: 'row' }}
|
|
>
|
|
{children}
|
|
</XStack>
|
|
</XStack>
|
|
)
|
|
|
|
/** The quiet link that lights up. Written five times across the two bars. */
|
|
export const Link = (props: ComponentProps<typeof Anchor>) => (
|
|
<Anchor
|
|
fontSize={14}
|
|
color="$quiet"
|
|
textDecorationLine="none"
|
|
cursor="pointer"
|
|
hoverStyle={{ color: '$ink' }}
|
|
{...props}
|
|
/>
|
|
)
|