diff --git a/.changeset/26080-readme-contributing-links.md b/.changeset/26080-readme-contributing-links.md new file mode 100644 index 00000000000..973123e27f0 --- /dev/null +++ b/.changeset/26080-readme-contributing-links.md @@ -0,0 +1,42 @@ +--- +'@object-ui/auth': patch +'@object-ui/collaboration': patch +'@object-ui/components': patch +'@object-ui/console': patch +'@object-ui/core': patch +'@object-ui/create-plugin': patch +'@object-ui/data-objectstack': patch +'@object-ui/fields': patch +'@object-ui/i18n': patch +'@object-ui/layout': patch +'@object-ui/mobile': patch +'@object-ui/permissions': patch +'@object-ui/plugin-ai': patch +'@object-ui/plugin-calendar': patch +'@object-ui/plugin-charts': patch +'@object-ui/plugin-chatbot': patch +'@object-ui/plugin-dashboard': patch +'@object-ui/plugin-designer': patch +'@object-ui/plugin-detail': patch +'@object-ui/plugin-editor': patch +'@object-ui/plugin-form': patch +'@object-ui/plugin-gantt': patch +'@object-ui/plugin-grid': patch +'@object-ui/plugin-kanban': patch +'@object-ui/plugin-list': patch +'@object-ui/plugin-map': patch +'@object-ui/plugin-markdown': patch +'@object-ui/plugin-report': patch +'@object-ui/plugin-timeline': patch +'@object-ui/plugin-view': patch +'@object-ui/providers': patch +'@object-ui/react': patch +'@object-ui/types': patch +--- + +docs: the README's Contributing Guide and Roadmap links point at the ObjectStack repository (objectstack#26080) + +Every package README linked its "Contributing Guide" and "Roadmap" to `CONTRIBUTING.md` and `ROADMAP.md` in the archived `objectstack-ai/objectui` repository. Those documents now live at the root of `objectstack-ai/objectstack`, which is where the links point; the `@object-ui/console` README's roadmap links move there too. No code, export or behaviour changes. + +Clause-②: no +Metadata-protocol: none diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a383e227013..a074a21162e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,6 +21,7 @@ each with its pointer. - [Making a Change](#making-a-change) - [Human Minimum](#human-minimum) - [Where Things Live](#where-things-live) +- [UI Workspace (`ui/`)](#ui-workspace-ui) - [Package Directory](#package-directory) - [Pull Request Process](#pull-request-process) - [Community](#community) @@ -197,11 +198,117 @@ same list. | `content/docs/references/` | Generated from the Zod schemas by `packages/spec/scripts/build-docs.ts`. Never edit it by hand. | | `content/docs/releases/` | Written at release time from changesets. Never edit it in a code pull request. | | `examples/` | The example apps. The *Examples* table in the [package directory](#package-directory) describes each one. | +| `ui/` | ObjectUI: the `@object-ui/*` packages, the Console's source and the objectui.org docs site. [UI Workspace](#ui-workspace-ui) below covers working there. | | [ARCHITECTURE.md](./ARCHITECTURE.md) | Design details, the plugin lifecycle and the dependency graph. | AGENTS.md (*Documentation Guardrails*) has the rules for every docs path, including what a new page needs before it shows up in the navigation. +## UI Workspace (`ui/`) + +`ui/` holds ObjectUI, the view layer: the `@object-ui/*` packages, the Console +(`ui/apps/console`) and the objectui.org docs site (`ui/apps/site`). It is a member of this +workspace, so the root `pnpm install` above installs it too, and +[ui/AGENTS.md](./ui/AGENTS.md) adds that tree's own rules to AGENTS.md: the spec-first and +contract-first commandments, Shadcn-native styling, actions as data. Its code is MIT-licensed +([License](#license)). What follows is only what differs from the rest of this guide. + +### UI commands + +Run these from `ui/`: + +```bash +pnpm exec turbo run build --filter='./*/*' --filter='!@object-ui/site' # Build every ui package (turbo, parallel & cached) +pnpm exec turbo run type-check --filter='./*/*' # Run tsc --noEmit across the ui packages (turbo) +pnpm exec turbo run lint --filter='./*/*' # Run eslint across the ui packages (turbo) +pnpm dev # The Console's Vite dev server, on :5180 +pnpm site:dev # The docs site, on http://localhost:3000 +pnpm docs:check-links # The internal-link check CI runs on ui docs +pnpm test:e2e # End-to-end tests (playwright) +``` + +turbo resolves a relative filter against the directory it is launched from, so the filter above +selects every package under `ui/packages/`, `ui/apps/` and `ui/examples/`. The tree has no +`build`, `type-check` or `lint` script of its own, because a `turbo run` in a member's script +would nest inside the root's. The ui packages spell the type-check task `type-check`, with a +hyphen. The Console dev server proxies its API calls to a backend as +[Getting Started](#getting-started) describes. + +### UI tests + +Run vitest **from `ui/`**, with paths written relative to it and **no `--`** before them: + +```bash +pnpm test # Run every vitest project (CI runs this) +pnpm exec vitest run packages/core/ # Run a single package's tests +pnpm exec vitest run packages/core/src/.test.ts # Run a single test file +pnpm exec vitest run apps/console/ # Run just the Console's tests +``` + +`pnpm --filter test` and `turbo run test` are fine too: every package's `test` script +names the ui root (`vitest run --root ../.. packages//`), so they run the same single +config CI does. What is still wrong is `cd packages/x && pnpm exec vitest`, and a path behind +`--`. Each of those moves vitest's root into a package, where the `unit` / `dom` / `dom-heavy` +projects match nothing and only `ui/apps/console` resolves: foreign files pass, your package +never runs, and the output is green. A guard **exits non-zero** on them and prints the +correct invocation. It is wired into every file vitest can pick up as a config: +`ui/vitest.config.mts`, `ui/apps/console/vitest.config.ts`, and every +`ui/packages//vite.config.ts`. The rejection looks like this: + +``` +vitest 调用被拒绝:从包目录跑 vitest 会静默跑错测试集 (objectui#3378) +... +正确跑法 —— 一律在【仓库根目录】执行,路径前【不要】加 `--`: + pnpm exec vitest run packages//src/.test.ts # 只跑一个文件 + pnpm exec vitest run packages// # 只跑一个包 + pnpm test # 全量(CI 跑的就是它) +``` + +Its "repository root" is `ui/`. The guard is `ui/scripts/vitest-invocation-guard.mjs`. + +### UI examples + +No directory under `ui/examples/` is a dev server: `hello-world` is a snippet to paste into +your own Vite or Next.js app (copy its app component and its schema), and `schema-catalog` is +a data package, the canonical JSON schemas the docs render, a smoke test mounts and AI agents +use as a few-shot corpus. Neither declares a `dev` script. +[`ui/examples/README.md`](./ui/examples/README.md) is the index. The app to run is the Console +(`pnpm dev` above). + +### UI layout + +| Path | Purpose | +| --- | --- | +| `ui/packages/*` | The published `@object-ui/*` packages, plus the private `vscode-extension`, `test-support` (test-only, never released), `runner` (workspace demo app, never released) and `app-shell` (the Console's shell and views, no longer published after 18.2.0) | +| `ui/apps/console` | The Console app (Vite + React), which `pnpm console:build` builds into the `@objectstack/console` package | +| `ui/apps/site` | The public docs site at (fumadocs) | +| `ui/examples/*` | The snippet and the schema catalog, see [UI examples](#ui-examples) | +| `ui/content/docs/` | The docs site's pages | +| `ui/docs/` | Internal engineering material (ADRs, audits); not part of the site | +| `ui/e2e/` | Playwright end-to-end tests | + +The [package directory](#package-directory) lists every `@object-ui/*` package by layer. + +### UI documentation + +The docs site's pages live in `ui/content/docs/`, and a page's path below it becomes its +route under the site's /docs base, so an internal link between pages is written +`[Quick Start](/docs/guide/quick-start)`, with the prefix. `ui/docs/` is not part of the site. + +- **A code block in an ADR or a dated audit is a specimen, not an example to copy.** Fence it + `plaintext`, never `ts` / `tsx`: a gate compiles the code fences of `ui/content/docs/`, and + a record edited until it compiles says something it never said. Code a reader may copy + belongs in `ui/content/docs/` or the skills tree. +- **A `json` fence must pass a strict `JSON.parse`.** A block annotated with comments or + trailing commas is fenced `jsonc`, and must still be one JSON document once those are + removed; a `${…}` expression stays on one line inside its string. +- **Internal links are checked offline.** `pnpm docs:check-links` resolves every relative + path and site route against the checkout, and CI runs it on every change. + +ObjectUI's [Quick Start](./ui/content/docs/guide/quick-start.md) and +[Component Registry](./ui/content/docs/guide/component-registry.md) guides are the place to +start when you add a component. + ## Package Directory
@@ -331,6 +438,77 @@ new page needs before it shows up in the navigation.
+
+Everything in ui/packages/ (ObjectUI, @object-ui/*, MIT), grouped by dependency weight — click to expand. + +Atoms and fields stay light; heavy widgets live in lazy-loaded plugins. + +#### Core + +| Package | Description | +| :--- | :--- | +| [`@object-ui/types`](ui/packages/types) | Pure TypeScript definitions — the protocol layer | +| [`@object-ui/core`](ui/packages/core) | Registry, validation, expression evaluation; zero React | +| [`@object-ui/react`](ui/packages/react) | React bindings and `SchemaRenderer` | +| [`@object-ui/components`](ui/packages/components) | Standard UI components (Tailwind + Shadcn) | +| [`@object-ui/fields`](ui/packages/fields) | Field renderers and registry | +| [`@object-ui/layout`](ui/packages/layout) | Layout components with React Router integration | + +#### Application shell + +| Package | Description | +| :--- | :--- | +| [`@object-ui/app-shell`](ui/packages/app-shell) | The Console's shell, views and Studio; a private workspace package, last published to npm as 18.2.0 | +| [`@object-ui/providers`](ui/packages/providers) | The upload adapter context the file and image fields upload through | +| [`@object-ui/auth`](ui/packages/auth) | `AuthProvider`, `useAuth`, `AuthGuard`, sign-in forms | +| [`@object-ui/permissions`](ui/packages/permissions) | Object / field / row-level permission guards and hooks | +| [`@object-ui/i18n`](ui/packages/i18n) | Language packs, RTL layout, date and currency formatting | +| [`@object-ui/mobile`](ui/packages/mobile) | Responsive components, PWA support, touch gestures | +| [`@object-ui/collaboration`](ui/packages/collaboration) | Presence, live cursors, conflict resolution, comment threads | +| [`@object-ui/console`](ui/apps/console) | Fork-ready runtime console with the full plugin set, shipped as a Hono plugin | + +#### Data adapters + +| Package | Description | +| :--- | :--- | +| [`@object-ui/data-objectstack`](ui/packages/data-objectstack) | ObjectStack data adapter | + +#### Plugins (lazy-loaded) + +| Package | Description | +| :--- | :--- | +| [`@object-ui/plugin-view`](ui/packages/plugin-view) | ObjectQL-integrated object views (grid, form, detail) | +| [`@object-ui/plugin-grid`](ui/packages/plugin-grid) | Advanced data grid | +| [`@object-ui/plugin-form`](ui/packages/plugin-form) | Advanced form components | +| [`@object-ui/plugin-detail`](ui/packages/plugin-detail) | Detail pages with sections, tabs, and related lists | +| [`@object-ui/plugin-list`](ui/packages/plugin-list) | Unified list view with view-type switching | +| [`@object-ui/plugin-kanban`](ui/packages/plugin-kanban) | Kanban boards with drag-and-drop (dnd-kit) | +| [`@object-ui/plugin-calendar`](ui/packages/plugin-calendar) | Calendar views | +| [`@object-ui/plugin-gantt`](ui/packages/plugin-gantt) | Gantt charts | +| [`@object-ui/plugin-timeline`](ui/packages/plugin-timeline) | Timelines | +| [`@object-ui/plugin-tree`](ui/packages/plugin-tree) | Tree and tree-grid views | +| [`@object-ui/plugin-map`](ui/packages/plugin-map) | Map visualization | +| [`@object-ui/plugin-charts`](ui/packages/plugin-charts) | Charts powered by Recharts | +| [`@object-ui/plugin-dashboard`](ui/packages/plugin-dashboard) | Dashboard layouts and widgets | +| [`@object-ui/plugin-report`](ui/packages/plugin-report) | Pivot tables, grouped aggregations, printable reports | +| [`@object-ui/plugin-designer`](ui/packages/plugin-designer) | Visual page, data-model, process, and report designers | +| [`@object-ui/plugin-editor`](ui/packages/plugin-editor) | Rich text editor powered by Monaco | +| [`@object-ui/plugin-markdown`](ui/packages/plugin-markdown) | Markdown rendering | +| [`@object-ui/plugin-chatbot`](ui/packages/plugin-chatbot) | Chatbot interface | +| [`@object-ui/plugin-ai`](ui/packages/plugin-ai) | Schema generation and conversational assistants (Vercel AI SDK) | + +#### Tooling + +| Package | Description | +| :--- | :--- | +| [`@object-ui/cli`](ui/packages/cli) | Scaffold, develop, build, and validate schema-driven apps | +| [`@object-ui/create-plugin`](ui/packages/create-plugin) | Scaffold a new Object UI plugin | +| [`@object-ui/runner`](ui/packages/runner) | Universal application runner for testing schemas (private workspace app, not published) | +| [`@object-ui/react-runtime`](ui/packages/react-runtime) | Trusted runtime execution for `kind: 'react'` pages | +| [`vscode-extension`](ui/packages/vscode-extension) | IntelliSense and live preview for schema files | + +
+ ## Pull Request Process ### Before Submitting @@ -376,6 +554,8 @@ that code lives. ## License By contributing, you agree that your contributions will be licensed under the -Apache License, Version 2.0 (see [LICENSE](./LICENSE) and [LICENSING.md](./LICENSING.md)). +Apache License, Version 2.0 (see [LICENSE](./LICENSE) and [LICENSING.md](./LICENSING.md)), +except contributions under `ui/`, which are licensed under the MIT License +([ui/LICENSE](./ui/LICENSE)). **Thank you for contributing to ObjectStack! 🚀** diff --git a/README.md b/README.md index 77c89c0fb4f..2aa27868912 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,31 @@ capability — drivers, server, auth, security, automation, AI — is a plugin. Design details, the plugin lifecycle state machine, and the dependency graph are in [ARCHITECTURE.md](./ARCHITECTURE.md). +### ObjectUI (`ui/`) + +`ui/` is the view layer of ObjectStack: a schema-driven React renderer that turns a JSON +schema or ObjectStack metadata into production React UI, usable on its own through the +MIT-licensed `@object-ui/*` packages, and the source of the Console. Its components follow +Shadcn's DOM structure and Tailwind utilities, it talks to any backend through one +`DataSource` interface, heavy views (grid, kanban, calendar, gantt, dashboards, visual +designers) are lazy-loaded plugins, and every schema is a TypeScript type in +`@object-ui/types`, derived from `@objectstack/spec`. It builds on ideas from +[Amis](https://github.com/baidu/amis), [Formily](https://github.com/alibaba/formily), +[shadcn/ui](https://ui.shadcn.com/) and [Tailwind CSS](https://tailwindcss.com/). + +

+ A kanban JSON schema on the left renders into a live kanban board on the right +

+ +| You want to… | Start here | Install | +| :--- | :--- | :--- | +| Render a JSON schema inside your React app | [Quick Start](./ui/content/docs/guide/quick-start.md) | `npm install @object-ui/react @object-ui/components` | +| Build a UI from a JSON file, no React code at all | [`@object-ui/cli`](./ui/packages/cli) | `npm install -g @object-ui/cli` | + +The guides are published at [objectui.org](https://www.objectui.org); working on `ui/` itself +is covered in [CONTRIBUTING.md](./CONTRIBUTING.md#ui-workspace-ui), and its packages are listed +in the [package directory](./CONTRIBUTING.md#package-directory). + ### CLI The CLI binary ships as both `os` and `objectstack`; `os --help` lists everything. diff --git a/ROADMAP.md b/ROADMAP.md index b394222e6f4..957b262a790 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -21,9 +21,10 @@ docs, adapters, services, plugins, and the bundled console integration. `environment`, not `project`: `OS_ENVIRONMENT_ID`, `X-Environment-Id`, `/api/v1/environments/:environmentId`, and `environment_id`. -- **Console UI:** framework serves the published ObjectUI console bundle from - `packages/console`; active UI source development happens in sibling repo - `../objectui`. +- **Console UI:** framework serves the ObjectUI console bundle from + `packages/console`; its source is the `ui/` workspace of this repository + (`ui/apps/console` and the `@object-ui/*` packages), and `pnpm console:build` + builds it into `packages/console`. - **Cloud publishing:** CLI publish/rollback target `/api/v1/cloud/environments/:environment/...` endpoints when pointed at an ObjectOS Cloud control plane. @@ -53,8 +54,26 @@ docs, adapters, services, plugins, and the bundled console integration. - Use `environment` for runtime/deployment identity. - Use `project` only for npm/monorepo/project-folder meaning, or when quoting historical ADR text. -- Link to sibling UI work as `../objectui` or the ObjectUI repo, not - `apps/studio`. +- Link to UI work by its path under `ui/`, never the archived ObjectUI + repository, `../objectui` or `apps/studio`. + +--- + +## ObjectUI (`ui/`) + +The view layer is planned and tracked like the rest of this repository; plans and +their status live where they are tracked, not in this file: + +- **Open work:** [issues](https://github.com/objectstack-ai/objectstack/issues), + filtered by the `area:*` labels for one feature axis and by `priority:*` for order. +- **Release targets:** [milestones](https://github.com/objectstack-ai/objectstack/milestones) + and the `target:*` labels. +- **What has shipped:** each `@object-ui/*` package's own `CHANGELOG.md`; + [ui/CHANGELOG.md](ui/CHANGELOG.md) is the frozen history of ObjectUI's own releases. +- **Design decisions:** the ADRs in [ui/docs/adr](ui/docs/adr) for the view layer. + +ObjectUI's long-form roadmap stopped at v3.3.2 (May 2026); it is in the git history of +`ui/ROADMAP.md`. --- diff --git a/ui/.changeset/README.md b/ui/.changeset/README.md index 23fdb05d392..c2abe65071e 100644 --- a/ui/.changeset/README.md +++ b/ui/.changeset/README.md @@ -107,6 +107,6 @@ that input when you need the current title instead of memorising one. ## Learn More - [Full Changesets Documentation](https://github.com/changesets/changesets) -- [Object UI Contributing Guide](../CONTRIBUTING.md#versioning-and-releases) +- [Contributing Guide, step 5: changesets](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md#making-a-change) - [Common Questions](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/ui/CHANGELOG.md b/ui/CHANGELOG.md index 7b043a6bcde..3d9427400c6 100644 --- a/ui/CHANGELOG.md +++ b/ui/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +> **Frozen history.** This file is no longer updated: current `@object-ui/*` history is each package's own `CHANGELOG.md`, and the plan is the repository [ROADMAP.md](https://github.com/objectstack-ai/objectstack/blob/main/ROADMAP.md). + This file is a **hand-curated summary** of notable changes across the monorepo. It is updated at release time by whoever cuts the release — it is not generated. The `Auto Changelog` workflow (`.github/workflows/changelog.yml`) exists to regenerate it with diff --git a/ui/CONTRIBUTING.md b/ui/CONTRIBUTING.md deleted file mode 100644 index fbe7ee522d0..00000000000 --- a/ui/CONTRIBUTING.md +++ /dev/null @@ -1,743 +0,0 @@ -# Contributing to Object UI - -Thank you for your interest in contributing to Object UI! This document provides guidelines and instructions for contributing to the project. - -## Table of Contents - -- [Getting Started](#getting-started) -- [Development Setup](#development-setup) -- [Development Workflow](#development-workflow) -- [Architecture Overview](#architecture-overview) -- [Writing Tests](#writing-tests) -- [Code Style](#code-style) -- [Commit Guidelines](#commit-guidelines) -- [Pull Request Process](#pull-request-process) -- [Documentation](#documentation) -- [Adding Components](#adding-components) -- [Questions & Support](#questions--support) - -## Getting Started - -### Prerequisites - -- **Node.js** 22.13 or higher (the floor root `package.json` declares in `engines.node`) -- **pnpm** 10 or higher (the required package manager — the workspace pins `pnpm@10.31.0` via `packageManager`) -- **Git** for version control -- Basic knowledge of React, TypeScript, and Tailwind CSS - -### Fork and Clone - -1. Fork the repository on GitHub -2. Clone your fork: - ```bash - git clone https://github.com/YOUR_USERNAME/objectui.git - cd objectui - ``` -3. Add upstream remote: - ```bash - git remote add upstream https://github.com/objectstack-ai/objectui.git - ``` - -## Development Setup - -### Install Dependencies - -```bash -# Install pnpm if you haven't -npm install -g pnpm - -# Build @objectstack/* at the commit .objectstack-sha pins, then install -# (`pnpm run setup` -- not `pnpm setup`, which is pnpm's own built-in command) -pnpm run setup -``` - -objectui resolves every `@objectstack/*` package from a build of the objectstack -commit that `.objectstack-sha` names, not from npm. `scripts/bump-objectstack.sh` -moves that pin; the dependency and lockfile section of `AGENTS.md` has the whole procedure. -The build is kept once per machine, in `$OBJECTSTACK_PIN_STORE` (default `~/.cache/objectstack-pin`, -or `$XDG_CACHE_HOME/objectstack-pin`), and copied into each new checkout; `pnpm objectstack:status` names it. - -### Configure Git Merge Driver for pnpm-lock.yaml - -To prevent merge conflicts in `pnpm-lock.yaml`, configure the custom merge driver: - -```bash -# Set the merge driver name -git config merge.pnpm-merge.name "pnpm-lock.yaml merge driver" - -# Set the merge driver command -git config merge.pnpm-merge.driver "pnpm install" -``` - -This configuration allows Git to automatically resolve conflicts in `pnpm-lock.yaml` by regenerating the lockfile using `pnpm install` instead of attempting a manual merge. - -**This step is not optional bookkeeping — it is the only place the driver is defined.** -`.gitattributes` routes `pnpm-lock.yaml` through a driver named `pnpm-merge`, but naming a -driver does not define one, and no CI workflow defines it either (none of them performs a -merge git carries out on the runner; see the "Lockfile Merge Driver" section of -`content/docs/guide/ci-cd-pipeline.md`). Skip this and the `git merge upstream/main` below -leaves conflict markers inside `pnpm-lock.yaml` instead of regenerating it. - -### Create a Branch - -```bash -# Sync with upstream -git fetch upstream -git checkout main -git merge upstream/main - -# Create a feature branch -git checkout -b feature/your-feature-name -``` - -## Development Workflow - -### Running Development Servers - -```bash -# Run the console app — the main dev playground (app shell + the full plugin set, -# including the visual designer, which mounts here rather than in a demo of its own) -pnpm dev - -# Run the documentation site -pnpm site:dev -``` - -### Building - -```bash -# Build all packages -pnpm build - -# Build specific package -cd packages/core && pnpm build -``` - -### Testing - -```bash -# Run all tests -pnpm test - -# Run tests in watch mode -pnpm test:watch - -# Run tests with UI (interactive) -pnpm test:ui - -# Generate coverage report -pnpm test:coverage -``` - -### Linting - -```bash -# Lint all packages -pnpm lint - -# Lint specific package -cd packages/react && pnpm lint -``` - -## Architecture Overview - -Object UI follows a modular monorepo architecture: - -``` -packages/ -├── types/ # TypeScript type definitions (Zero dependencies) -├── core/ # Core logic, validation, registry (Zero React) -├── react/ # React bindings and SchemaRenderer -├── components/ # UI components (Tailwind + Shadcn) -├── designer/ # Visual schema editor -├── plugin-charts/ # Chart components plugin -└── plugin-editor/ # Rich text editor plugin -``` - -### Key Principles - -1. **Protocol Agnostic**: Core never depends on specific backends -2. **Tailwind Native**: All styling via Tailwind utility classes -3. **Type Safety**: Strict TypeScript everywhere -4. **Tree Shakable**: Modular imports, no monolithic bundles -5. **Zero React in Core**: Core package has no React dependencies - -See the [Architecture Overview](./content/docs/guide/architecture.md) guide for details. - -## Writing Tests - -### Test Structure - -All tests should be placed in `__tests__` directories within the source code. We use **Vitest** and **React Testing Library**. - -```typescript -import { describe, it, expect } from 'vitest' -import { render, screen } from '@testing-library/react' -import { MyComponent } from './MyComponent' - -describe('MyComponent', () => { - it('should render correctly', () => { - render() - expect(screen.getByText('Expected Text')).toBeInTheDocument() - }) - - it('should handle user interaction', async () => { - const { user } = render() - await user.click(screen.getByRole('button')) - expect(screen.getByText('Clicked')).toBeInTheDocument() - }) -}) -``` - -### Testing Best Practices - -- Write tests for all new features -- Test user interactions, not implementation details -- Use meaningful test descriptions -- Maintain or improve code coverage (current thresholds: 63% lines, 43% functions, 40% branches, 62% statements) -- Aim to gradually increase coverage toward the long-term goal of 80%+ across all metrics -- Test edge cases and error states - -## Code Style - -### TypeScript Guidelines - -```typescript -// ✅ Good: Explicit types, clear naming -interface UserData { - id: string - name: string - email: string -} - -function getUserById(id: string): UserData | null { - // implementation -} - -// ❌ Bad: Implicit any, unclear naming -function get(x) { - // implementation -} -``` - -### React Component Guidelines - -```tsx -// ✅ Good: TypeScript, named exports, clear props -interface ButtonProps { - label: string - onClick: () => void - variant?: 'primary' | 'secondary' -} - -export function Button({ label, onClick, variant = 'primary' }: ButtonProps) { - return ( - - ) -} - -// ❌ Bad: No types, default export, inline styles -export default function Button(props) { - return -} -``` - -### Styling Guidelines - -- **Always use Tailwind**: Never use inline styles or CSS modules -- **Use `cn()` utility**: For conditional classes -- **Extract repeated classes**: Create reusable class combinations -- **Follow Shadcn patterns**: Match the style of existing components - -```tsx -// ✅ Good -
- {children} -
- -// ❌ Bad -
- {children} -
-``` - -### General Guidelines - -- Use meaningful variable and function names -- Keep functions small and focused (< 50 lines) -- Add JSDoc comments for public APIs -- Avoid deep nesting (max 3 levels) -- Use early returns to reduce complexity - -## Commit Guidelines - -We follow [Conventional Commits](https://www.conventionalcommits.org/): - -### Commit Types - -- `feat:` - New features -- `fix:` - Bug fixes -- `docs:` - Documentation changes -- `test:` - Adding or updating tests -- `chore:` - Maintenance tasks (deps, config) -- `refactor:` - Code refactoring (no behavior change) -- `perf:` - Performance improvements -- `style:` - Code style changes (formatting) - -### Examples - -```bash -feat: add date picker component -fix: resolve schema validation error -docs: update installation guide -test: add tests for SchemaRenderer -chore: update dependencies -refactor: simplify expression evaluator -``` - -### Commit Message Format - -``` -: - - - -