← المدونة

⁦Text.js 0.1⁩

يقدّم ⁦Text.js 0.1⁩ موفّق ⁦React 19⁩ وتخطيط Yoga و ⁦App Router⁩ قائمًا على نظام الملفات للتطبيقات التي تُعرض في وحدة تحكم DevTools.

Adam

وُضع وسم الإصدار ⁦Text.js 0.1⁩. إنه أول إصدار يضم الطبقات الثلاث كلها: ترسم @textjs/core الإطارات في وحدة التحكم، وتعرض @textjs/react مكتبة ⁦React 19⁩ في تلك الإطارات، وتضيف textjs نظام ⁦App Router⁩ وواجهة سطر أوامر.

نظام ⁦App Router⁩

المسارات مجلدات في app/، تتبع اصطلاحات ⁦App Router⁩ في Next.js. هذا قالب dashboard من create-text-app:

app/├── layout.tsx├── page.tsx├── not-found.tsx├── deployments/│   └── [id]/│       └── page.tsx└── api/    └── metrics/        └── route.ts

يحيط التخطيط بكل صفحة تحته ويحافظ على حالته عبر التنقل. يقبل <Link> الخاصية shortcut، فيكفي مفتاح واحد لاتباع الرابط، وتنسّق activeClassName الرابط المؤدي إلى المسار الحالي:

app/layout.tsxtsx
import type { ReactNode } from "react";import { Box, KeyHint, Text, useTheme, type Metadata } from "textjs";import Link from "textjs/link";export const metadata: Metadata = { title: { default: "Acme", template: "%s · Acme" } };export default function RootLayout({ children }: { children?: ReactNode }): ReactNode {  const theme = useTheme();  return (    <Box className="flex-col w-full h-full">      <Box className="flex-row h-1 px-1 gap-3 bg-surface shrink-0">        <Text bold color={theme.fg} wrap="nowrap">          ▼ Acme        </Text>        <Link href="/" shortcut="1" className="text-muted no-underline" activeClassName="text-fg bold">          1 Metrics        </Link>        <Link href="/deployments/dpl_a1" shortcut="2" className="text-muted no-underline" activeClassName="text-fg bold">          2 Latest deploy        </Link>      </Box>      <Box className="grow flex-col px-2 pt-1">{children}</Box>      <Box className="flex-row h-1 gap-2 pl-6 shrink-0 bg-surface">        <KeyHint keys="1-2" label="navigate" />        <KeyHint keys="tab" label="focus" />        <KeyHint keys="F2" label="devtools" />      </Box>    </Box>  );}

تعمل المقاطع الديناميكية بالطريقة نفسها كما في Next.js. يتحول [id] إلى معامل، ويلتقط [...slug] بقية المسار، ويطابق [[...slug]] المسار الأب أيضًا. تتقدم المقاطع الثابتة على الديناميكية، وتنظّم مجموعات المسارات مثل (marketing) الملفات دون إضافة شيء إلى عنوان URL.

app/deployments/[id]/page.tsxtsx
import { Box, Text, useInput } from "textjs";import { notFound, useParams, useRouter } from "textjs/navigation";import { DEPLOYMENTS } from "../../../lib/data";export default function DeploymentPage() {  const router = useRouter();  const { id } = useParams<{ id: string }>();  const deployment = DEPLOYMENTS.find((d) => d.id === id);  useInput((e) => {    if (e.key === "escape") router.back();  });  if (!deployment) notFound();  return (    <Box className="flex-col gap-1">      <Text bold>{deployment.id}</Text>      <Text>{deployment.branch}</Text>    </Box>  );}

يحيط loading.tsx و error.tsx المقطع بحدود Suspense وحدود الأخطاء. يتلقى مكوّن الخطأ الخطأ ودالة reset:

app/deployments/error.tsxtsx
import { Box, Text, useInput, type ErrorComponentProps } from "textjs";export default function DeploymentsError({ error, reset }: ErrorComponentProps) {  useInput((e) => {    if (e.key === "r") reset();  });  return (    <Box className="flex-col grow items-center justify-center gap-1">      <Text bold>Something went wrong loading deployments.</Text>      <Text>{error.message}</Text>    </Box>  );}

توجد معالجات المسارات في app/api وتعيد كائن Response قياسيًا:

app/api/metrics/route.tsts
export function GET(): Response {  return Response.json({ cpu: Math.random(), memory: Math.random(), at: new Date().toISOString() });}

يحافظ الموجّه على مزامنة window.location عبر history.pushState، فتعمل وظائف الرجوع والتقدم والروابط العميقة، وتُكتب قيمة metadata.title في document.title. يرسم التطبيق في وحدة التحكم، وتستضيف الصفحة لوحة تركيز تجمع المدخلات.

واجهة سطر الأوامر

  • يشغّل text dev أداة Vite مع ⁦React Fast Refresh⁩. يحدّث حفظ الملف وحدة التحكم في مكانها.
  • يكتب text build بناءً للإنتاج من التطبيق ومعالجات مساراته.
  • يقدّم text start البناء ومعالجات المسارات.

ينشئ create-text-app هيكل مشروع من قالب starter أو dashboard.

المفتّش

اضغط Ctrl+` أو F2 في تطبيق قيد التشغيل لفتح المفتّش [▼] داخل وحدة التحكم. يعرض المسار المطابق ومعاملاته، وحجم الإطار وعدد عناصر span وتوقيتات المراحل، وعدد الإطارات التي تخطتها بوابة التغييرات. يرسم W تخطيط Yoga بهيئة هيكل سلكي.

إضافات أخرى في 0.1

تأتي @textjs/react بمكوّنات تستخدم تسمية PascalCase (Box، Text، ScrollBox، Input، Textarea، Select، Tabs، Code، Markdown، Diff، Modal، Spinner)، وأدوات className على نمط Tailwind تعمل بوحدات الخلايا، وسمات. يعمل التخطيط باستخدام Yoga في WebAssembly.

توجد القائمة الكاملة في سجل التغييرات.