mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
Every word the landing, the header menus, the phone sheet, the footer,
the help corner and the way in (sign-in, sign-up, the reset, the
invitation, the callback, onboarding, the 404) write goes through
@hanzo/i18n's t(): one sentence is one message, its figures, names and
links arguments; copy written as data is phrase('…') where written and
t(label) where drawn. Plans, the chart, the API states and the lines
lib/kai and lib/enso build for the landing do the same.
Right to left: <html lang dir> is set before the first paint (the
package's bootScript first in the head); a figure, clock, range or
price outside a sentence is isolated; sides are logical gui props, the
layout's [data-join] corners logical, a bar grows from the start;
arrows along the line mirror (Onward for "words ->" links). The repo
dates read in the reader's language.
Gates select by slot, never by an English label (rtl, help). New gate
translated.spec.ts: in Arabic the landing at 1440 and 390, every menu
open, the phone sheet, sign-in, sign-up and the app signed in hold no
authored English, nothing scrolls sideways, every range is isolated;
French the same for English's commonest words. What another package
draws with no words prop is listed by name (@hanzo/ui's Footer label,
@hanzo/build's composer row and suggestions).
@hanzo/i18n 0.5.3 (the catalogs: 1,443 keys, every offered locale
complete), @hanzo/app 0.2.1 (the app's words). The link gate imports
the terms versions from @hanzo/app, the one SDK main now resolves.
66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
'use client'
|
|
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
import { Text, View, XStack, YStack } from '@hanzo/ui'
|
|
import { useGrow, useStill } from './chrome'
|
|
|
|
/** A bar grows in ten times its measured time, so the eye can follow the slowest. */
|
|
const SLOW = 10
|
|
|
|
/**
|
|
* One bar of a measured figure, drawn to scale against `top`: filled for ours,
|
|
* outlined for the other side. A timed bar grows in `SLOW` times its
|
|
* milliseconds; any other kind of figure says how long with `duration`.
|
|
*
|
|
* The bar grows from the start of the line, the right on a right-to-left page,
|
|
* and `text` (a figure and its unit: `~43 tok/s`, `0.4 ms`) keeps its own order
|
|
* there. `label` is drawn as given: the caller translates it.
|
|
*/
|
|
export function Lane({
|
|
label,
|
|
value,
|
|
top,
|
|
play,
|
|
ours,
|
|
text,
|
|
duration,
|
|
}: {
|
|
label?: string
|
|
value: number
|
|
top: number
|
|
play: boolean
|
|
ours: boolean
|
|
text?: string
|
|
duration?: number
|
|
}) {
|
|
const { dir } = useI18n()
|
|
const still = useStill()
|
|
const ref = useGrow(play, still, { duration: duration ?? Math.max(60, value * SLOW), from: 'scaleX(0)', to: 'scaleX(1)' })
|
|
return (
|
|
<YStack gap={6} py={label ? 8 : 2}>
|
|
{label ? (
|
|
<XStack justify="space-between" gap={12}>
|
|
<Text fontSize="$2" lineHeight="$2" color="var(--foreground)">
|
|
{label}
|
|
</Text>
|
|
<Text fontFamily="$mono" fontSize="$2" lineHeight="$2" color="var(--foreground)" $platform-web={{ fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap' }}>
|
|
<bdi dir="ltr">{text}</bdi>
|
|
</Text>
|
|
</XStack>
|
|
) : null}
|
|
<View height={10} rounded={9999} borderWidth={1} borderColor="var(--border)" overflow="hidden" $platform-web={{ borderRadius: '9999px' }}>
|
|
<View
|
|
ref={ref}
|
|
height="100%"
|
|
rounded={9999}
|
|
width={`${Math.max(0.4, (value / top) * 100).toFixed(2)}%`}
|
|
bg={ours ? 'var(--foreground)' : 'transparent'}
|
|
borderWidth={ours ? 0 : 1}
|
|
borderColor="var(--foreground)"
|
|
$platform-web={{ borderRadius: '9999px', transformOrigin: dir === 'rtl' ? 'right center' : 'left center' }}
|
|
/>
|
|
</View>
|
|
</YStack>
|
|
)
|
|
}
|