MobTranslate styleguide

Getting Started

Install the private workspace package, load its real stylesheets and verify a usable React interface.

Supported delivery model

@mobtranslate/ui is a private source package in packages/ui. It is not a published npm installation contract. Its main and types entries point to src/index.ts, so the consuming bundler must compile TypeScript and React JSX. This styleguide uses Next.js 16, React 19 and Tailwind CSS 4; that is the currently verified web setup.

The package and its two consumers, styleguide and web, require React and React DOM ^19.2.7. Use the lockfile’s matching runtime and React 19 types. React 18 is outside this release contract; a wider peer range would need its own compatibility evidence.

RequirementActual workspace contract
Package dependency"@mobtranslate/ui": "workspace:*"
Component entryimport { Button, Input } from "@mobtranslate/ui"
Source compilationNext transpilePackages: ["@mobtranslate/ui"]
Token stylesheet@mobtranslate/ui/src/tokens/tokens.css
Component stylesheet@mobtranslate/ui/src/components/components.css
Styling pipelineTailwind 4 through @tailwindcss/postcss
Native platformsDOM/CSS components; not React Native or native Android/iOS widgets

Run this styleguide

Run these commands from the repository root. Use the repository’s declared pnpm 9.15.0 package manager and the lockfile; a different manager/version is a separate compatibility check. The filtered installation includes the UI dependency without launching unrelated apps. Install first, then generate/check assets and start one server on the chosen port.

bash
pnpm --filter styleguide... install --frozen-lockfile
pnpm --filter styleguide dev --hostname 127.0.0.1
# Local preview: http://127.0.0.1:3003

Add another workspace consumer

Replace my-app with an existing package name from apps/. Add the workspace dependency to that app; a registry-only install outside this repository cannot satisfy workspace:*. Match the app’s React and React DOM versions. Keep server-only credentials outside client component code.

bash
pnpm --filter my-app add "@mobtranslate/ui@workspace:*"
pnpm --filter my-app add -D tailwindcss@4.3.1 @tailwindcss/postcss@4.3.1 postcss@8.5.15

Configure compilation and styles

In next.config.js, enable transpilePackages for the source package. In postcss.config.mjs, register @tailwindcss/postcss. The following global CSS paths resolve against the actual installed workspace package. The @source path assumes globals.css is in apps/my-app/app/; adjust the relative source path if the file moves. Import the global stylesheet once from the app root layout.

  • Next config: module.exports = { transpilePackages: ["@mobtranslate/ui"] };
  • PostCSS config: export default { plugins: { "@tailwindcss/postcss": {} } };
  • Root layout: import "./globals.css". Use a real html lang value and a meaningful main landmark.
  • Do not rely on a TypeScript path alias to prove package resolution. This styleguide now resolves the actual workspace dependency.
css
@import "tailwindcss";
@import "@mobtranslate/ui/src/tokens/tokens.css";
@import "@mobtranslate/ui/src/components/components.css";
@source "../../../packages/ui/src";

First checked interactive example

This example is compiled from the same source displayed below. It has a persistent label, connected help/error text, explicit submission, retained input and an honest local result. It does not invent language content or pretend a request was published.

Use your own text. This local demo does not return language content.

tsx
'use client';

import { useId, useState } from 'react';
import { Button, Input } from '@mobtranslate/ui';

export function EntryFormExample() {
  const id = useId();
  const [text, setText] = useState('');
  const [error, setError] = useState('');
  const [status, setStatus] = useState('');
  return <form noValidate className="space-y-3" onSubmit={event => {
    event.preventDefault();
    if (!text.trim()) {
      setError('Enter search text before trying this example.');
      setStatus('');
      event.currentTarget.querySelector<HTMLInputElement>('input')?.focus();
      return;
    }
    setError('');
    setStatus(`Local example received “${text}”. No search or publication was sent.`);
  }}>
    <label htmlFor={id} className="block font-medium">Search text</label>
    <Input id={id} value={text} required state={error ? 'error' : 'default'}
      aria-describedby={`${id}-help${error ? ` ${id}-error` : ''}`}
      onChange={event => { setText(event.target.value); setError(''); setStatus(''); }} />
    <p id={`${id}-help`} className="text-sm">Use your own text. This local demo does not return language content.</p>
    {error && <p id={`${id}-error`} role="alert" className="text-sm">{error}</p>}
    <Button type="submit">Try local form</Button>
    <p role="status" className="text-sm">{status}</p>
  </form>;
}

Server and client boundaries

  • Keep useState, event handlers, browser storage and DOM access in client components. Put "use client" before imports in the file that defines the interactive boundary.
  • Server-render the document structure and source-backed content where practical. Pass serializable values across the boundary; do not expose secrets in props.
  • Choose controlled state when the app needs to validate or persist it. Use defaultValue/defaultOpen for an uncontrolled initial value, not as a substitute for later updates.
  • A disabled submit button is not a request handler. Implement pending, cancellation, recovery and the actual persistence outcome in the consuming app.

Verify the setup

Stop the development server before starting production on the same port. The build checks TypeScript; it does not replace browser operation, accessibility review or verification of real data writes.

bash
pnpm --filter styleguide lint
pnpm --filter styleguide typecheck
pnpm --filter styleguide tokens:check
pnpm --filter styleguide examples:check
pnpm --filter styleguide build
pnpm --filter styleguide start --hostname 127.0.0.1
# In another terminal, with agent-browser installed:
pnpm --filter styleguide test:browser

Troubleshooting

SymptomCheckRecovery
Cannot resolve @mobtranslate/uiWorkspace dependency and filtered installInstall from the repository root; inspect the package link.
Unstyled controlsBoth package /src CSS imports and PostCSS setupLoad global CSS once; inspect a real computed token value.
Missing utility stylesTailwind source scanning and app-relative @sourceInclude the package source; use literal class names for generated variants.
Invalid hook or duplicate ReactReact/React DOM versions and dependency graphAlign the consumer’s versions and investigate duplicate runtime copies.
Browser navigation timeout during startupCold compilation, memory and disk contentionInspect the same process/port and wait for an actual successful route response. An observation timeout alone does not justify restarting it; test the built production server.
Light choice changes with system themeExplicit .light and .dark plus mt-theme keyUse the verified theme controller and system/storage listeners.