mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
chore(root): streamline agent guidance and skills
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# 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/src/utils/api-reference-overrides.ts` (the shared map the builder imports and the reference pages invert for slug lookup):
|
||||
|
||||
```ts
|
||||
export const NAME_OVERRIDES: Record<string, string> = {
|
||||
'pip-button': 'PiPButton',
|
||||
'airplay-button': 'AirPlayButton',
|
||||
};
|
||||
```
|
||||
|
||||
Use overrides only when the standard conversion fails (e.g., acronyms like PiP). Prefer aligning component naming with the standard conversion when possible.
|
||||
|
||||
The same map covers media elements whose PascalCase name doesn't kebab-case to their element tag name (e.g. `'hlsjs-video': 'HlsJsVideo'`). It is keyed by the generated-reference file slug regardless of component vs. media.
|
||||
|
||||
## 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.
|
||||
```
|
||||
Reference in New Issue
Block a user