mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-28 13:09:51 +01:00
Compare commits
9
Commits
841b5708ae
...
4e586253c0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e586253c0 | ||
|
|
08980158e4 | ||
|
|
1e917c7b89 | ||
|
|
8d3678ddcb | ||
|
|
6a58c5ea1d | ||
|
|
b9bbf22f2c | ||
|
|
c99ed0cb53 | ||
|
|
cef18d4f64 | ||
|
|
824169fc25 |
No files matched your search
Vendored
+1
@@ -249,6 +249,7 @@
|
||||
"winrate",
|
||||
"wireframe",
|
||||
"Woah",
|
||||
"wooorm",
|
||||
"WOTB",
|
||||
"wotblitz",
|
||||
"wotbreplay",
|
||||
|
||||
@@ -210,12 +210,14 @@
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"@types/three": "^0.180.0",
|
||||
"@vite-pwa/astro": "^1.1.0",
|
||||
"@wooorm/starry-night": "^3.9.0",
|
||||
"astro": "^5.14.4",
|
||||
"astro-favicons": "^3.1.5",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"cssnano": "^7.1.2",
|
||||
"fuzzysort": "^3.1.0",
|
||||
"googleapis": "^171.1.0",
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"immer": "^10.1.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"postcss": "^8.5.6",
|
||||
@@ -1262,6 +1264,8 @@
|
||||
|
||||
"@webgpu/types": ["@webgpu/[email protected]", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="],
|
||||
|
||||
"@wooorm/starry-night": ["@wooorm/[email protected]", "", { "dependencies": { "@types/hast": "^3.0.0", "import-meta-resolve": "^4.0.0", "vscode-oniguruma": "^2.0.0", "vscode-textmate": "^9.0.0" } }, "sha512-LXVGKfYhTuFhoRuPAHz2XolS/J45L4lI/lCSIBugDpklXYDUPrJyA8tk17u7G32fcFaGODJXH/YDwQDfUXdPRw=="],
|
||||
|
||||
"abort-controller": ["[email protected]", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
|
||||
|
||||
"acorn": ["[email protected]", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||
@@ -2932,6 +2936,10 @@
|
||||
|
||||
"vscode-nls": ["[email protected]", "", {}, "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="],
|
||||
|
||||
"vscode-oniguruma": ["[email protected]", "", {}, "sha512-poJU8iHIWnC3vgphJnrLZyI3YdqRlR27xzqDmpPXYzA93R4Gk8z7T6oqDzDoHjoikA2aS82crdXFkjELCdJsjQ=="],
|
||||
|
||||
"vscode-textmate": ["[email protected]", "", {}, "sha512-n2uGbUcrjhUEBH16uGA0TvUfhWwliFZ1e3+pTjrkim1Mt7ydB41lV08aUvsi70OlzDWp6X7Bx3w/x3fAXIsN0Q=="],
|
||||
|
||||
"vscode-uri": ["[email protected]", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="],
|
||||
|
||||
"web-namespaces": ["[email protected]", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
|
||||
|
||||
@@ -1,16 +1,45 @@
|
||||
export function literals(
|
||||
string: string,
|
||||
literals?: Record<string, string | number | undefined>
|
||||
literals?: Record<string, string | number | undefined>,
|
||||
) {
|
||||
for (const key in literals) {
|
||||
const mutated = string.replaceAll(`{${key}}`, `${literals[key]}`);
|
||||
|
||||
if (import.meta.env.DEV && mutated === string) {
|
||||
console.warn(`Could not find literal {${key}} in string "${string}"`);
|
||||
}
|
||||
|
||||
string = mutated;
|
||||
string = string.replaceAll(`{${key}}`, `${literals[key]}`);
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
export function literalsArray<Type, Literal = Type | string>(
|
||||
string: string,
|
||||
literals?: Record<string, Literal>,
|
||||
) {
|
||||
if (!literals) return [string];
|
||||
|
||||
let array: (string | Literal)[] = [string];
|
||||
|
||||
for (const key in literals) {
|
||||
const value = literals[key];
|
||||
const next: (string | Literal)[] = [];
|
||||
|
||||
for (const chunk of array) {
|
||||
if (typeof chunk !== "string") {
|
||||
next.push(chunk);
|
||||
continue;
|
||||
}
|
||||
|
||||
const parts = chunk.split(`{${key}}`);
|
||||
|
||||
for (let index = 0; index < parts.length; index++) {
|
||||
if (parts[index]) next.push(parts[index]);
|
||||
|
||||
if (index < parts.length - 1) {
|
||||
next.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
array = next;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
@@ -122,6 +122,7 @@
|
||||
"pb": "Protocol Buffer methods",
|
||||
"media": "Media methods",
|
||||
"no_docs": "This method has no documentation.",
|
||||
"test": "Test"
|
||||
"test": "Test",
|
||||
"view_full": "View full types"
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,14 @@
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"@types/three": "^0.180.0",
|
||||
"@vite-pwa/astro": "^1.1.0",
|
||||
"@wooorm/starry-night": "^3.9.0",
|
||||
"astro": "^5.14.4",
|
||||
"astro-favicons": "^3.1.5",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"cssnano": "^7.1.2",
|
||||
"fuzzysort": "^3.1.0",
|
||||
"googleapis": "^171.1.0",
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"immer": "^10.1.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"postcss": "^8.5.6",
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
import ApiMacroSee from "./ApiMacroSee.astro";
|
||||
import ApiMacroType from "./ApiMacroType.astro";
|
||||
import { MarkdownCustom } from "./MarkdownCustom";
|
||||
|
||||
interface Props {
|
||||
body: string;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const macroPattern = /@(\w+) (.+)/;
|
||||
const macros: Record<string, string[]> = {};
|
||||
|
||||
const macroComponents = {
|
||||
see: ApiMacroSee,
|
||||
type: ApiMacroType,
|
||||
};
|
||||
|
||||
const { body: bodyOriginal, locale } = Astro.props;
|
||||
let body = "";
|
||||
|
||||
for (const line of bodyOriginal.split("\n")) {
|
||||
const match = line.match(macroPattern);
|
||||
|
||||
if (match === null) {
|
||||
body += `${line}\n`;
|
||||
continue;
|
||||
}
|
||||
|
||||
const macro = match[1];
|
||||
const value = match[2];
|
||||
|
||||
if (macro in macros) {
|
||||
macros[macro].push(value);
|
||||
} else {
|
||||
macros[macro] = [value];
|
||||
}
|
||||
}
|
||||
---
|
||||
|
||||
<style>
|
||||
.api-description {
|
||||
display: flex;
|
||||
|
||||
.gutter {
|
||||
width: var(--space-2);
|
||||
background: linear-gradient(transparent, var(--gray-6) var(--space-4));
|
||||
|
||||
margin: 0 var(--space-4);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
|
||||
padding-top: var(--space-4);
|
||||
padding-bottom: var(--space-3);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="api-description">
|
||||
<div class="gutter"></div>
|
||||
<div class="content">
|
||||
<MarkdownCustom {body} />
|
||||
|
||||
<!-- {"see" in macros && <ApiMacroSee {locale} value={macros.see} />}
|
||||
{"type" in macros && <ApiMacroType {locale} value={macros.type} />} -->
|
||||
|
||||
{
|
||||
Object.entries(macroComponents).map(([macro, Component]) => {
|
||||
if (!(macro in macros)) return null;
|
||||
|
||||
return macros[macro].map((value) => {
|
||||
return <Component {locale} value={value} />;
|
||||
});
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import { api } from "../core/api/dynamic";
|
||||
import ApiDescription from "./ApiDescription.astro";
|
||||
import { ApiTester } from "./ApiTester";
|
||||
import { MarkdownCustom } from "./MarkdownCustom";
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
@@ -11,19 +11,17 @@ interface Props {
|
||||
|
||||
const { locale, api: apiData } = Astro.props;
|
||||
const strings = await api.strings(locale);
|
||||
const hasSlugs = apiData.id.includes("[");
|
||||
const body = apiData.data.docs ?? strings.api.no_docs;
|
||||
---
|
||||
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<ApiTester client:idle {locale} path={apiData.id} />
|
||||
|
||||
<MarkdownCustom body={apiData.data.docs ?? strings.api.no_docs} />
|
||||
<ApiDescription {locale} {body} />
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
import { sluggify } from "@blitzkit/core";
|
||||
import { Code } from "./Code";
|
||||
import { Link } from "./Link";
|
||||
import { Text } from "./Text";
|
||||
|
||||
interface Props {
|
||||
value: string;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const bodyPattern = /^([a-z0-9-\/\.\[\]]+) (.+)$/;
|
||||
|
||||
const { value, locale } = Astro.props;
|
||||
|
||||
const match = value.match(bodyPattern);
|
||||
|
||||
if (match === null) {
|
||||
throw new Error(`Invalid value for ApiMacroSee: ${value}`);
|
||||
}
|
||||
|
||||
const path = match[1];
|
||||
const message = match[2];
|
||||
---
|
||||
|
||||
<Text>
|
||||
<Text lowContrast weight="medium" color="tomato">
|
||||
<Code>@see</Code>
|
||||
</Text>
|
||||
|
||||
<Link underline="never" href={`#${sluggify(path)}`}>
|
||||
<Code>{path}</Code>
|
||||
</Link>
|
||||
|
||||
{message}
|
||||
</Text>
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
import { existsSync } from "fs";
|
||||
import { readFile } from "fs/promises";
|
||||
import { Link } from "./Link";
|
||||
import { api } from "../core/api/dynamic";
|
||||
import HighlightedCodeBlock from "./HighlightedCodeBlock.astro";
|
||||
import { Text } from "./Text";
|
||||
import { ArrowBottomRightIcon } from "@radix-ui/react-icons";
|
||||
import { Code } from "./Code";
|
||||
|
||||
interface Props {
|
||||
value: string;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { value, locale } = Astro.props;
|
||||
const strings = await api.strings(locale);
|
||||
|
||||
const roots = ["src/protos", "../closed/protos"];
|
||||
|
||||
const lang = "proto";
|
||||
const importPattern = /import "(.+)";/gm;
|
||||
const messagePattern = /message .+ {\s*\n(.+\s*\n)+}/gm;
|
||||
|
||||
const explored = new Set<string>();
|
||||
let messages: string[] = [];
|
||||
|
||||
await pullMessages(`${roots[0]}/${value}.proto`);
|
||||
|
||||
async function pullMessages(path: string) {
|
||||
if (explored.has(path)) return;
|
||||
|
||||
explored.add(path);
|
||||
|
||||
const file = await readFile(path);
|
||||
const content = file.toString();
|
||||
const imports = content.matchAll(importPattern);
|
||||
|
||||
for (const _import of imports) {
|
||||
for (const root of roots) {
|
||||
const path = `${root}/${_import[1]}`;
|
||||
|
||||
if (existsSync(path)) {
|
||||
await pullMessages(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const matchedMessages = content.matchAll(messagePattern);
|
||||
|
||||
for (const message of matchedMessages) {
|
||||
messages = [message[0], ...messages];
|
||||
}
|
||||
}
|
||||
|
||||
const content = messages.join("\n\n");
|
||||
|
||||
const indexPattern = /^( +).+\.(.+ = \d+;)$/m;
|
||||
|
||||
let stripped = "";
|
||||
|
||||
for (const line of content.split("\n")) {
|
||||
const matches = line.match(indexPattern);
|
||||
|
||||
if (matches === null) {
|
||||
stripped += `${line}\n`;
|
||||
continue;
|
||||
}
|
||||
|
||||
stripped += `${matches[1]}${matches[2]}\n`;
|
||||
}
|
||||
|
||||
stripped = stripped.replaceAll(" ", " ");
|
||||
---
|
||||
|
||||
<style>
|
||||
.macro {
|
||||
color: var(--gray-11);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.types {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
position: relative;
|
||||
|
||||
&:not([data-expanded="true"]) {
|
||||
max-height: 16rem;
|
||||
}
|
||||
|
||||
&[data-expanded="true"] {
|
||||
.overlay {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background: linear-gradient(transparent, var(--gray-1));
|
||||
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const viewers = document.querySelectorAll(".view-full");
|
||||
|
||||
for (const viewer of viewers) {
|
||||
viewer.addEventListener("click", () => {
|
||||
viewer.parentElement!.parentElement!.dataset.expanded = "true";
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="macro">
|
||||
<Text lowContrast weight="medium" color="tomato">
|
||||
<Code>@types</Code>
|
||||
</Text>
|
||||
|
||||
<ArrowBottomRightIcon />
|
||||
</div>
|
||||
|
||||
<div class="types">
|
||||
<HighlightedCodeBlock {lang} content={stripped} />
|
||||
|
||||
<div class="overlay">
|
||||
<Link underline="always" href="#" className="view-full">
|
||||
{strings.api.view_full}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { sluggify } from "@blitzkit/core";
|
||||
import { PlayIcon } from "@radix-ui/react-icons";
|
||||
import { Fragment, useState } from "react";
|
||||
import {
|
||||
LocaleProvider,
|
||||
type LocaleAcceptorProps,
|
||||
@@ -6,8 +8,8 @@ import {
|
||||
import { useStrings } from "../../hooks/useStrings";
|
||||
import { Button } from "../Button";
|
||||
import { Code } from "../Code";
|
||||
import { Heading } from "../Heading";
|
||||
import { Link } from "../Link";
|
||||
import { Text } from "../Text";
|
||||
import { TextField } from "../TextField";
|
||||
import styles from "./index.module.css";
|
||||
|
||||
@@ -39,19 +41,19 @@ function Content({ path }: Props) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.tester}>
|
||||
<Heading size="3">
|
||||
<div className={styles.tester} id={sluggify(path)}>
|
||||
<Text weight="medium">
|
||||
<Code className={styles.title}>
|
||||
{path.split(slugPattern).map((text, index) => {
|
||||
const slug = slugs[index - 1];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Fragment key={index}>
|
||||
{index > 0 && (
|
||||
<TextField
|
||||
variant="form"
|
||||
className={styles.slug}
|
||||
placeholder={`${slug}`}
|
||||
monospace
|
||||
placeholder={`[${slug}]`}
|
||||
align="center"
|
||||
autoWidth
|
||||
onChange={(event) => {
|
||||
@@ -63,14 +65,16 @@ function Content({ path }: Props) {
|
||||
/>
|
||||
)}
|
||||
<span key={index}>{text}</span>
|
||||
</>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</Code>
|
||||
</Heading>
|
||||
</Text>
|
||||
|
||||
<Link underline="never" href={href} target="_blank">
|
||||
<Button>{strings.api.test}</Button>
|
||||
<Button>
|
||||
{strings.api.test} <PlayIcon />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.code {
|
||||
font-family: var(--font-family-mono);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
.code {
|
||||
font: inherit;
|
||||
font-family: var(--font-family-mono);
|
||||
|
||||
white-space: pre;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
&[data-variant="solid"] {
|
||||
background-color: var(--gray-3);
|
||||
|
||||
border-radius: var(--space-3);
|
||||
|
||||
padding: var(--space-4);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,17 @@
|
||||
import type { ComponentProps } from "react";
|
||||
import { classNames } from "../../core/ui/classNames";
|
||||
import "./index.css";
|
||||
import styles from "./index.module.css";
|
||||
|
||||
export interface CodeProps extends ComponentProps<"code"> {}
|
||||
export interface CodeProps extends ComponentProps<"code"> {
|
||||
variant?: "ghost" | "solid";
|
||||
}
|
||||
|
||||
export function Code({ className, ...props }: CodeProps) {
|
||||
return <code className={classNames("code", className)} {...props} />;
|
||||
export function Code({ className, variant = "ghost", ...props }: CodeProps) {
|
||||
return (
|
||||
<code
|
||||
data-variant={variant}
|
||||
className={classNames(styles.code, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
import { all, createStarryNight } from "@wooorm/starry-night";
|
||||
import { HighlightedCodeContent } from "./HighlightedCodeContent";
|
||||
|
||||
interface Props {
|
||||
lang: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
const { lang, content } = Astro.props;
|
||||
|
||||
const starryNight = await createStarryNight(all);
|
||||
const scope = starryNight.flagToScope(lang);
|
||||
|
||||
if (scope === undefined && lang.length > 0) {
|
||||
throw new Error(`Unsupported language: ${lang}`);
|
||||
}
|
||||
|
||||
const tree =
|
||||
lang.length === 0 ? content : starryNight.highlight(content, scope!);
|
||||
---
|
||||
|
||||
<HighlightedCodeContent {tree} />
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { Root } from "hast";
|
||||
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
|
||||
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
||||
import { Code } from "./Code";
|
||||
|
||||
interface Props {
|
||||
tree: Root | string;
|
||||
}
|
||||
|
||||
export function HighlightedCodeContent({ tree }: Props) {
|
||||
const node =
|
||||
typeof tree === "string"
|
||||
? tree
|
||||
: toJsxRuntime(tree, { Fragment, jsx, jsxs });
|
||||
|
||||
return <Code variant="solid" children={node} />;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
.link {
|
||||
text-decoration-color: currentColor;
|
||||
|
||||
display: flex;
|
||||
display: inline;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<style is:global>
|
||||
@import "@wooorm/starry-night/style/dark";
|
||||
</style>
|
||||
-4
@@ -2,10 +2,6 @@
|
||||
font-size: var(--font-size-regular);
|
||||
color: var(--gray-12);
|
||||
|
||||
&[data-low-contrast="true"] {
|
||||
color: var(--white-a9);
|
||||
}
|
||||
|
||||
&[data-size="minor"] {
|
||||
font-size: var(--font-size-minor);
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
import type { ComponentProps } from "react";
|
||||
import { classNames } from "../../core/ui/classNames";
|
||||
import "./index.css";
|
||||
import type { Color } from "../../core/ui/color";
|
||||
import styles from "./index.module.css";
|
||||
|
||||
export interface TextProps extends ComponentProps<"span"> {
|
||||
weight?: "light" | "regular" | "medium" | "bold" | "black";
|
||||
lowContrast?: boolean;
|
||||
size?: "regular" | "minor" | "major";
|
||||
align?: "left" | "center" | "right";
|
||||
color?: Color;
|
||||
}
|
||||
|
||||
export function Text({
|
||||
@@ -16,15 +18,17 @@ export function Text({
|
||||
weight,
|
||||
style,
|
||||
align,
|
||||
color = "gray",
|
||||
...props
|
||||
}: TextProps) {
|
||||
return (
|
||||
<span
|
||||
className={classNames("text", className)}
|
||||
className={classNames(styles.text, className)}
|
||||
data-low-contrast={lowContrast}
|
||||
data-size={size}
|
||||
data-weight={weight}
|
||||
data-align={align === "left" ? undefined : align}
|
||||
style={{ color: `var(--${color}-${lowContrast ? 10 : 12})` }}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -5,15 +5,30 @@
|
||||
|
||||
gap: var(--space-3);
|
||||
|
||||
border-radius: var(--max-size);
|
||||
|
||||
background-color: var(--gray-1);
|
||||
box-shadow: var(--shadow-interactive), var(--shadow-cavity);
|
||||
cursor: text;
|
||||
|
||||
font-size: var(--font-size-regular);
|
||||
font: inherit;
|
||||
color: var(--gray-11);
|
||||
|
||||
&[data-variant="bubble"] {
|
||||
border-radius: var(--max-size);
|
||||
|
||||
background-color: var(--gray-1);
|
||||
box-shadow: var(--shadow-interactive), var(--shadow-cavity);
|
||||
|
||||
input {
|
||||
padding: var(--space-3) var(--space-4);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-variant="form"] {
|
||||
border-bottom: var(--space-1) solid var(--gray-6);
|
||||
|
||||
input {
|
||||
padding: var(--space-2);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-has-icon="true"] {
|
||||
padding-left: var(--space-3);
|
||||
|
||||
@@ -34,7 +49,7 @@
|
||||
color: var(--gray-9);
|
||||
|
||||
input::placeholder {
|
||||
color: var(--gray-9);
|
||||
color: var(--gray-6);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,14 +66,12 @@
|
||||
border: none;
|
||||
cursor: inherit;
|
||||
|
||||
font-size: inherit;
|
||||
font-weight: medium;
|
||||
padding: var(--space-3) var(--space-4);
|
||||
font: inherit;
|
||||
|
||||
color: var(--gray-12);
|
||||
|
||||
&::placeholder {
|
||||
color: var(--gray-11);
|
||||
color: var(--gray-9);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@@ -71,9 +84,5 @@
|
||||
&[data-align="right"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&[data-monospace="true"] {
|
||||
font-family: var(--font-family-mono);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,8 @@ import "./index.css";
|
||||
export interface TextFieldProps extends ComponentProps<"input"> {
|
||||
children?: ReactNode;
|
||||
align?: "left" | "center" | "right";
|
||||
monospace?: boolean;
|
||||
autoWidth?: boolean;
|
||||
variant?: "bubble" | "form";
|
||||
}
|
||||
|
||||
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
@@ -22,13 +22,13 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
{
|
||||
children,
|
||||
className,
|
||||
monospace,
|
||||
autoWidth,
|
||||
placeholder,
|
||||
align,
|
||||
disabled,
|
||||
value,
|
||||
onChange,
|
||||
variant = "bubble",
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
@@ -54,11 +54,11 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
className={classNames("text-field", className)}
|
||||
data-has-icon={children !== undefined}
|
||||
data-disabled={disabled}
|
||||
data-variant={variant}
|
||||
>
|
||||
{children}
|
||||
<input
|
||||
data-align={align === "left" ? undefined : align}
|
||||
data-monospace={monospace}
|
||||
disabled={disabled}
|
||||
ref={input}
|
||||
onChange={handleChange}
|
||||
|
||||
@@ -26,13 +26,13 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-5) var(--space-4);
|
||||
padding: var(--space-5) var(--space-5);
|
||||
box-sizing: border-box;
|
||||
|
||||
backdrop-filter: var(--blur-tint);
|
||||
|
||||
@media (width > 40rem) {
|
||||
padding: var(--space-6) var(--space-4);
|
||||
padding: var(--space-6) var(--space-5);
|
||||
}
|
||||
|
||||
.centered {
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
import "@radix-ui/colors/amber-dark.css";
|
||||
import { getCollection } from "astro:content";
|
||||
import ApiGroup from "../../../components/ApiGroup.astro";
|
||||
import ColorScale from "../../../components/ColorScale.astro";
|
||||
import { Heading } from "../../../components/Heading";
|
||||
import { Section } from "../../../components/Section";
|
||||
import SyntaxStyles from "../../../components/SyntaxStyles.astro";
|
||||
import ToolBanner from "../../../components/ToolBanner.astro";
|
||||
import { api } from "../../../core/api/dynamic";
|
||||
import { tools } from "../../../core/tools/tools";
|
||||
@@ -24,10 +26,13 @@ paths.sort((a, b) => a.path.localeCompare(b.path));
|
||||
---
|
||||
|
||||
<BaseLayout {locale} accent="brown">
|
||||
<SyntaxStyles slot="head" />
|
||||
<ColorScale color="tomato" slot="head" />
|
||||
|
||||
<ToolBanner {locale} tool={tools.api} slot="pre-app" />
|
||||
|
||||
<Section>
|
||||
<Heading>{strings.api.json}</Heading>
|
||||
<Heading size="2">{strings.api.json}</Heading>
|
||||
<ApiGroup
|
||||
{locale}
|
||||
apis={collection.filter((api) => api.id.endsWith(".json"))}
|
||||
@@ -35,7 +40,7 @@ paths.sort((a, b) => a.path.localeCompare(b.path));
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<Heading>{strings.api.pb}</Heading>
|
||||
<Heading size="2">{strings.api.pb}</Heading>
|
||||
<ApiGroup
|
||||
{locale}
|
||||
apis={collection.filter((api) => api.id.endsWith(".pb"))}
|
||||
@@ -43,7 +48,7 @@ paths.sort((a, b) => a.path.localeCompare(b.path));
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<Heading>{strings.api.media}</Heading>
|
||||
<Heading size="2">{strings.api.media}</Heading>
|
||||
<ApiGroup
|
||||
{locale}
|
||||
apis={collection.filter(
|
||||
|
||||
@@ -10,9 +10,12 @@ export const getStaticPaths = (async () => {
|
||||
}) satisfies GetStaticPaths;
|
||||
|
||||
/**
|
||||
* Returns data on an avatar based on its id. @see avatars/list.json for a list
|
||||
* of all avatar ids.
|
||||
* Returns data on an avatar based on its `id`. Do not use the `.webp` URLs
|
||||
* from the returned data as they point to Wargaming's servers which may update
|
||||
* over time, out of sync with BlitzKit.
|
||||
*
|
||||
* @see avatars/list.json for all avatar ids.
|
||||
* @see avatars/[id].webp for avatar images.
|
||||
* @type avatar
|
||||
*/
|
||||
export async function GET({ params }: APIContext<never, { id: string }>) {
|
||||
|
||||
Reference in new issue
Block a user