wip(docs): i18n (#12681)

This commit is contained in:
Adam
2026-02-09 11:34:35 -06:00
committed by GitHub
parent f74c0339cc
commit dc53086c1e
642 changed files with 192745 additions and 509 deletions
+62 -9
View File
@@ -1,16 +1,55 @@
import { createSignal, onCleanup, splitProps } from "solid-js"
import { createContext, createSignal, onCleanup, splitProps, useContext } from "solid-js"
import type { JSX } from "solid-js/jsx-runtime"
import { IconCheckCircle, IconHashtag } from "../icons"
export type ShareMessages = { locale: string } & Record<string, string>
const shareContext = createContext<ShareMessages>()
export function ShareI18nProvider(props: { messages: ShareMessages; children: JSX.Element }) {
return <shareContext.Provider value={props.messages}>{props.children}</shareContext.Provider>
}
export function useShareMessages() {
const value = useContext(shareContext)
if (value) {
return value
}
throw new Error("ShareI18nProvider is required")
}
export function normalizeLocale(locale: string) {
return locale === "root" ? "en" : locale
}
export function formatNumber(value: number, locale: string) {
return new Intl.NumberFormat(normalizeLocale(locale)).format(value)
}
export function formatCurrency(value: number, locale: string) {
return new Intl.NumberFormat(normalizeLocale(locale), {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(value)
}
export function formatCount(value: number, locale: string, singular: string, plural: string) {
const unit = value === 1 ? singular : plural
return `${formatNumber(value, locale)} ${unit}`
}
interface AnchorProps extends JSX.HTMLAttributes<HTMLDivElement> {
id: string
}
export function AnchorIcon(props: AnchorProps) {
const [local, rest] = splitProps(props, ["id", "children"])
const [copied, setCopied] = createSignal(false)
const messages = useShareMessages()
return (
<div {...rest} data-element-anchor title="Link to this message" data-status={copied() ? "copied" : ""}>
<div {...rest} data-element-anchor title={messages.link_to_message} data-status={copied() ? "copied" : ""}>
<a
href={`#${local.id}`}
onClick={(e) => {
@@ -32,7 +71,7 @@ export function AnchorIcon(props: AnchorProps) {
<IconHashtag width={18} height={18} />
<IconCheckCircle width={18} height={18} />
</a>
<span data-element-tooltip>Copied!</span>
<span data-element-tooltip>{messages.copied}</span>
</div>
)
}
@@ -59,19 +98,33 @@ export function createOverflow() {
}
}
export function formatDuration(ms: number): string {
export function formatDuration(ms: number, locale: string): string {
const normalized = normalizeLocale(locale)
const ONE_SECOND = 1000
const ONE_MINUTE = 60 * ONE_SECOND
if (ms >= ONE_MINUTE) {
const minutes = Math.floor(ms / ONE_MINUTE)
return minutes === 1 ? `1min` : `${minutes}mins`
return new Intl.NumberFormat(normalized, {
style: "unit",
unit: "minute",
unitDisplay: "narrow",
maximumFractionDigits: 0,
}).format(Math.floor(ms / ONE_MINUTE))
}
if (ms >= ONE_SECOND) {
const seconds = Math.floor(ms / ONE_SECOND)
return `${seconds}s`
return new Intl.NumberFormat(normalized, {
style: "unit",
unit: "second",
unitDisplay: "narrow",
maximumFractionDigits: 0,
}).format(Math.floor(ms / ONE_SECOND))
}
return `${ms}ms`
return new Intl.NumberFormat(normalized, {
style: "unit",
unit: "millisecond",
unitDisplay: "narrow",
maximumFractionDigits: 0,
}).format(ms)
}