Skip to content

Commit dfabef0

Browse files
committed
docs: add Docusaurus documentation site
1 parent 4a32ee9 commit dfabef0

34 files changed

Lines changed: 22930 additions & 0 deletions

.github/workflows/deploy.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
pages: write
10+
id-token: write
11+
12+
concurrency:
13+
group: "pages"
14+
cancel-in-progress: false
15+
16+
jobs:
17+
build:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Node
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: '20'
27+
cache: 'npm'
28+
29+
- name: Install dependencies
30+
run: npm ci
31+
32+
- name: Build
33+
run: npm run build
34+
35+
- name: Upload artifact
36+
uses: actions/upload-pages-artifact@v3
37+
with:
38+
path: lib
39+
40+
deploy:
41+
environment:
42+
name: github-pages
43+
url: ${{ steps.deployment.outputs.page_url }}
44+
runs-on: ubuntu-latest
45+
needs: build
46+
steps:
47+
- name: Deploy to GitHub Pages
48+
id: deployment
49+
uses: actions/deploy-pages@v4

.github/workflows/test-deploy.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Test Build on PR
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
jobs:
9+
test-build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v4
14+
15+
- name: Setup Node
16+
uses: actions/setup-node@v4
17+
with:
18+
node-version: '20'
19+
cache: 'npm'
20+
21+
- name: Install dependencies
22+
run: npm ci
23+
24+
- name: Build
25+
run: npm run build

AGENTS.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# EFX-FORMS KNOWLEDGE BASE
2+
3+
**Generated:** 2025-05-18
4+
**Commit:** HEAD
5+
**Branch:** main
6+
7+
## OVERVIEW
8+
9+
Effector-based React form library. TypeScript, flat src/ structure, Playwright CT testing. Dual CJS/ESM build.
10+
11+
## STRUCTURE
12+
13+
```
14+
efx-forms/
15+
├── src/ # All source code (flat, no subdirs)
16+
├── src/tests/ # Component tests (Playwright CT)
17+
├── playwright/ # Test infrastructure
18+
├── lib/ # Build output (gitignored)
19+
└── package.json # Main: index.js, Types: index.d.ts
20+
```
21+
22+
## WHERE TO LOOK
23+
24+
| Task | Location | Notes |
25+
|------|----------|-------|
26+
| Core form logic | src/form.ts | 12.5K lines, main state machine |
27+
| Components | src/*Component.tsx | FormComponent, FieldComponent, etc. |
28+
| Hooks | src/use*.ts | 12 hooks: useForm, useField, etc. |
29+
| Types | src/types.ts | 9.7K lines, all TS interfaces |
30+
| Validators | src/validators.ts | Built-in validators (required, email, etc.) |
31+
| Utils | src/utils.ts | truthyFy, shapeFy, flattenObjectKeys |
32+
| Tests | src/tests/*.spec.tsx | Playwright CT, .spec.tsx naming |
33+
| Test infra | playwright/ | CT config, fixtures |
34+
35+
## CODE MAP
36+
37+
| Symbol | Type | Location | Role |
38+
|--------|------|----------|------|
39+
| Form | Component | src/ | Main form wrapper, context provider |
40+
| Field | Component | src/ | Field wrapper, validation, state sync |
41+
| getForm | Function | src/forms.ts | Registry: get form instance by name |
42+
| useFormInstance | Hook | src/ | Get form from context |
43+
| $values | Store | src/form.ts | Form values store |
44+
| $errors | Store | src/form.ts | Form errors store |
45+
| submit | Effect | src/form.ts | Form submit effect |
46+
| OnSendParams | Type | src/tests/components/Hooks/ | Test state capture |
47+
48+
## CONVENTIONS
49+
50+
**Naming:**
51+
- Components: `*Component.tsx` (FormComponent, FieldComponent)
52+
- Hooks: `use*.ts` (useForm, useField, useFieldData)
53+
- Tests: `*.spec.tsx` or `*.spec.ts`
54+
55+
**Selectors:**
56+
- Use `data-test` attributes (NOT data-testid)
57+
- Centralized in `src/tests/selectors.ts` as `sel` object
58+
59+
**State Capture (tests):**
60+
- `OnSendParams` type captures form snapshots
61+
- `SendFormData` helper component with "Set Data" button
62+
- Pattern: `await sendData.click()` then verify `data.form.values`
63+
64+
**Re-render (tests):**
65+
- `component.update(<Component ... />)` for prop changes
66+
67+
## ANTI-PATTERNS (THIS PROJECT)
68+
69+
**TypeScript:**
70+
-`Record<string, any>` - pervasive throughout codebase
71+
-`Store<any>` - constants.ts, useStoreProp hooks
72+
-`ComponentType<any>` - FieldComponent props
73+
- ❌ Index signatures: `[any: string]: any` in types.ts
74+
- ✅ ESLint: `@typescript-eslint/no-explicit-any` is OFF
75+
76+
**Build:**
77+
- ❌ Custom `npmize` bash script (not standard npm pack)
78+
- ❌ No GitHub Actions (uses .sisyphus/ custom CI)
79+
80+
**Structure:**
81+
- ❌ Flat src/ - no components/, hooks/, utils/ directories
82+
- ❌ Tests in src/tests/ (excluded via tsconfig)
83+
84+
## UNIQUE STYLES
85+
86+
**Sub-path imports:**
87+
- `efx-forms/validators` → src/validators.ts
88+
- `efx-forms/FormDataProvider` → src/FormDataProvider.tsx
89+
- `efx-forms/utils` → src/utils.ts
90+
- No `exports` field in package.json - works via direct file paths
91+
92+
**Build output:**
93+
- `lib/` - CJS (default)
94+
- `lib/mjs/` - ESM (created by npmize with `{"type": "module"}`)
95+
96+
**Test patterns:**
97+
- Playwright CT (not Jest/Vitest)
98+
- No mocking - real components via `mount()`
99+
- Multi-browser: Chromium + Firefox
100+
101+
## COMMANDS
102+
103+
```bash
104+
# Build (CJS + ESM)
105+
npm run build # rm -rf lib/* && tsc && ./npmize
106+
107+
# Publish
108+
npm run publish-lib # Publish to npm
109+
npm run publish-beta # Publish with --tag beta
110+
npm run publish-dryrun # Dry run
111+
112+
# Test
113+
npm test # Playwright CT
114+
npm run test:open # Playwright UI mode
115+
116+
# Lint
117+
npm run lint # ESLint
118+
```
119+
120+
## NOTES
121+
122+
**Gotchas:**
123+
- `lib/` is gitignored - build before publish
124+
- `noImplicitAny: false` - allows implicit any
125+
- Tests excluded from TypeScript build
126+
- Beta releases: `npm run publish-beta`
127+
- Dual CJS/ESM requires npmize post-build step
128+
129+
**Peer Dependencies:**
130+
- effector: >=23.0.0 <24.0.0
131+
- effector-react: >=23.0.0 <24.0.0
132+
- lodash: ^4.17.0
133+
- react: >=16.8.0 <20.0.0

docs-site/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
build
3+
.docusaurus

docs-site/docs/api/components.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
sidebar_position: 1
3+
---
4+
5+
# Core Components Overview
6+
7+
EFX-Forms provides a set of React components for building forms with Effector state management. This page gives you a quick overview of all available components.
8+
9+
## Component List
10+
11+
| Component | Import Path | Description |
12+
|-----------|-------------|-------------|
13+
| [`Form`](./form-component.md) | `efx-forms` | Main form wrapper and context provider |
14+
| [`Field`](./field-component.md) | `efx-forms` | Field wrapper with validation and state sync |
15+
| [`FormDataProvider`](./form-data-provider.md) | `efx-forms/FormDataProvider` | Subscribe to form values and errors |
16+
| [`FieldDataProvider`](./field-data-provider.md) | `efx-forms/FieldDataProvider` | Subscribe to individual field values |
17+
| [`IfFormValues`](./if-form-values.md) | `efx-forms/IfFormValues` | Conditional rendering based on form values |
18+
| [`IfFieldValue`](./if-field-value.md) | `efx-forms/IfFieldValue` | Conditional rendering based on field value |
19+
20+
## Basic Usage Pattern
21+
22+
All components work together within a form context:
23+
24+
```tsx
25+
import { Form, Field } from 'efx-forms';
26+
import { FormDataProvider } from 'efx-forms/FormDataProvider';
27+
import { required, email } from 'efx-forms/validators';
28+
29+
const Input = ({ label, error, value, onChange, onBlur, ...props }) => (
30+
<div>
31+
<label>{label}</label>
32+
<input value={value || ''} onChange={onChange} onBlur={onBlur} {...props} />
33+
{error && <span className="error">{error}</span>}
34+
</div>
35+
);
36+
37+
const TextField = (props) => <Field Field={Input} {...props} />;
38+
39+
function MyForm() {
40+
const handleSubmit = (values) => {
41+
console.log('Form submitted:', values);
42+
};
43+
44+
return (
45+
<Form name="contact-form" onSubmit={handleSubmit}>
46+
<TextField name="name" label="Name" validators={[required()]} />
47+
<TextField name="email" label="Email" validators={[required(), email()]} />
48+
49+
<FormDataProvider>
50+
{({ values, errors }) => (
51+
<pre>{JSON.stringify({ values, errors }, null, 2)}</pre>
52+
)}
53+
</FormDataProvider>
54+
55+
<button type="submit">Submit</button>
56+
</Form>
57+
);
58+
}
59+
```
60+
61+
## Component Categories
62+
63+
### Form Components
64+
65+
- **Form**: The root component that creates form context and manages state
66+
- **Field**: Individual field wrapper that connects inputs to form state
67+
68+
### Data Provider Components
69+
70+
- **FormDataProvider**: Access form-wide data (values, errors, state)
71+
- **FieldDataProvider**: Access individual field data (value, active, touched)
72+
73+
### Conditional Components
74+
75+
- **IfFormValues**: Show/hide content based on form values
76+
- **IfFieldValue**: Show/hide content based on single field value
77+
78+
## Next Steps
79+
80+
- [Form Component - Detailed API](./form-component.md)
81+
- [Field Component - Detailed API](./field-component.md)
82+
- [Getting Started Guide](../getting-started.md)

0 commit comments

Comments
 (0)