mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
102 lines
4.5 KiB
Markdown
102 lines
4.5 KiB
Markdown
# Builder Conventions
|
|
|
|
Naming and file placement conventions required by the api-docs-builder at `site/scripts/api-docs-builder/`.
|
|
|
|
## File Locations
|
|
|
|
| File | Path | Purpose |
|
|
|------|------|---------|
|
|
| Core | `packages/core/src/core/ui/{name}/{name}-core.ts` | Props, State, defaultProps |
|
|
| Data attrs | `packages/core/src/core/ui/{name}/{name}-data-attrs.ts` | Data attribute definitions |
|
|
| CSS vars | `packages/core/src/core/ui/{name}/{name}-css-vars.ts` | CSS custom property definitions (optional) |
|
|
| HTML element | `packages/html/src/ui/{name}/{name}-element.ts` | Custom element with `static tagName` |
|
|
| React parts | `packages/react/src/ui/{name}/index.parts.ts` | Multi-part detection (optional) |
|
|
|
|
## Naming Requirements
|
|
|
|
The builder derives PascalCase from kebab-case using `kebabCase` from es-toolkit. All interfaces and exports must follow this pattern:
|
|
|
|
| Convention | Example (play-button) |
|
|
|-----------|----------------------|
|
|
| Props interface | `PlayButtonProps` |
|
|
| State interface | `PlayButtonState` |
|
|
| Core class | `PlayButtonCore` |
|
|
| Data attrs export | `PlayButtonDataAttrs` |
|
|
| CSS vars export | `PlayButtonCSSVars` |
|
|
| HTML element class | `PlayButtonElement` |
|
|
| HTML tag name | `static tagName = 'media-play-button'` |
|
|
|
|
## NAME_OVERRIDES
|
|
|
|
When kebab-to-pascal conversion doesn't produce the correct name, add an override in `site/scripts/api-docs-builder/src/index.ts`:
|
|
|
|
```ts
|
|
const NAME_OVERRIDES: Record<string, string> = {
|
|
'pip-button': 'PiPButton',
|
|
};
|
|
```
|
|
|
|
Use overrides only when the standard conversion fails (e.g., acronyms like PiP). Prefer aligning component naming with the standard conversion when possible.
|
|
|
|
## Multi-Part Components
|
|
|
|
**Detection**: Presence of `packages/react/src/ui/{name}/index.parts.ts`.
|
|
|
|
**Non-local re-export filtering**: Only exports with source paths starting with `./` are treated as parts. Re-exports from other directories (e.g., `../slider/index.parts`) are filtered out. This prevents domain variant components (TimeSlider, VolumeSlider) from inheriting base component parts.
|
|
|
|
**Single-part fallback**: When filtering leaves only one part (typically Root), the component uses single-part mode — the remaining part's props/state/data-attrs are promoted to the top level, not nested under `parts`.
|
|
|
|
**Primary part identification**: The part whose React source file instantiates the component's Core class (matches `new \w+Core\(`). The primary part receives the shared core props/state/data-attrs/css-vars.
|
|
|
|
**Non-primary parts**: Each gets its own element file at `{name}-{part}-element.ts`. Element class must be `{Name}{Part}Element` (e.g., `TimeGroupElement`).
|
|
|
|
**Framework-divergent parts**: All parts get `platforms.react`. Parts with a matching HTML element file also get `platforms.html`. The renderer filters parts by framework — React-only parts are hidden in HTML docs.
|
|
|
|
**Part descriptions**: Extracted from JSDoc on the React component export:
|
|
```tsx
|
|
/** Displays a formatted time value. */
|
|
export const Value = ...;
|
|
```
|
|
|
|
## JSDoc Extraction
|
|
|
|
- **Data attribute descriptions**: From JSDoc comments on each property in the data-attrs export object
|
|
- **Part descriptions**: From JSDoc on React component exports in their `.tsx` files
|
|
- **Prop/state descriptions**: From JSDoc on interface properties in the core file
|
|
|
|
### Util JSDoc
|
|
|
|
Util exports (hooks, controllers, factories, selectors) have their own JSDoc conventions for `@param`, `@label`, and `@public` tags. See `references/util-conventions.md` → "JSDoc Conventions".
|
|
|
|
## Common Failures
|
|
|
|
The builder fails silently for many issues — data just won't appear in the JSON:
|
|
|
|
| Symptom | Cause |
|
|
|---------|-------|
|
|
| No JSON generated | Core file missing or Props interface not found |
|
|
| Empty props | Interface not named `{PascalCase}Props` |
|
|
| Empty state | Interface not named `{PascalCase}State` |
|
|
| No data attributes | File missing or export not named `{PascalCase}DataAttrs` |
|
|
| No CSS vars | File missing or export not named `{PascalCase}CSSVars` |
|
|
| No HTML tag | Element file missing or no `static tagName` |
|
|
| No part descriptions | Missing JSDoc on React component exports |
|
|
| Wrong PascalCase | Need a `NAME_OVERRIDES` entry |
|
|
|
|
## Validation
|
|
|
|
```bash
|
|
# Generate JSON
|
|
pnpm -F site api-docs
|
|
|
|
# Check component output
|
|
cat site/src/content/generated-component-reference/{name}.json
|
|
|
|
# Check util output
|
|
cat site/src/content/generated-util-reference/{slug}.json
|
|
|
|
# Verify schema
|
|
# The builder validates against ComponentReferenceSchema / UtilReferenceSchema before writing.
|
|
# Schema errors are logged as errors and cause exit code 1.
|
|
```
|