mirror of
https://github.com/hunvreus/basecoat.git
synced 2026-11-11 20:58:18 +00:00
100 lines
6.7 KiB
Markdown
100 lines
6.7 KiB
Markdown
# Agent Rules
|
|
|
|
## Communication
|
|
- Keep answers concise, technical, and to the point.
|
|
- Do not use filler or glazing openers.
|
|
- Keep explanations MECE: separate facts, decisions, risks, and open questions.
|
|
- If scope is partial, state exactly what was not included.
|
|
- Challenge incorrect assumptions with evidence from code, docs, or upstream sources.
|
|
|
|
## Project Intent
|
|
- Basecoat is a Tailwind CSS, vanilla HTML, CSS, and JavaScript implementation of shadcn/ui's visual language for non-React stacks.
|
|
- Basecoat maps upstream shadcn/ui concepts onto simpler semantic markup; it is not a React, Radix, Base UI, `cn-*`, or `data-slot` DOM port.
|
|
- Prefer the browser platform: native elements, semantic HTML, CSS state selectors, and small vanilla JS only when needed.
|
|
|
|
## Source Boundaries
|
|
- Do not hand-edit build outputs:
|
|
- `dist/**`
|
|
- `templates/**`
|
|
- `site/dist/**`
|
|
- `site/public/assets/js/**`
|
|
- `site/public/fragments/**`
|
|
- Generated source entrypoints such as `src/css/basecoat-vega.css` are committed, but must be regenerated through `scripts/generate-css-entrypoints.js` or build scripts, not manually maintained.
|
|
|
|
## Public API and Markup
|
|
- Keep public component APIs small: usually one root class, semantic child elements, documented ARIA/data attributes only when needed, and minimal JS for behavior.
|
|
- Avoid required child classes when meaningful markup can identify children: `input`, `textarea`, `select`, `button`, `a`, `label`, `fieldset`, `legend`, `header`, `section`, `footer`, `svg`, `kbd`, `hr`.
|
|
- Add new child classes, wrappers, `data-*` attributes, macro arguments, or public selectors only as intentional API.
|
|
- Do not add roles for styling; ARIA must describe behavior or accessibility state.
|
|
- Prefer intentional divergence over awkward imitation when upstream markup does not map cleanly to Basecoat.
|
|
|
|
## Accessibility
|
|
- Start with the native element that matches the control.
|
|
- Use `<fieldset>` and `<legend>` for grouped form controls when appropriate.
|
|
- Use native `<dialog>` where possible.
|
|
- Keep composite-widget keyboard behavior predictable: skip disabled items, respect orientation, and handle Escape/Enter/Space according to role.
|
|
- Disabled custom items must be skipped by pointer and keyboard interactions.
|
|
- Use logical CSS utilities/properties for RTL; flip only icons whose meaning is directional.
|
|
|
|
## CSS
|
|
- Component CSS in `src/css/components/*.css` owns structure, layout primitives, accessibility selectors, and behavior hooks.
|
|
- Style-pack CSS in `src/css/styles/*.css` owns visual choices: color, radius, shadow/ring, typography, spacing, variants, and state visuals.
|
|
- Each style bundle must stand alone. Do not load Vega/default and then undo it in another style.
|
|
- Avoid defensive resets that only compensate for another style pack.
|
|
- Prefer Tailwind logical utilities (`ps`, `pe`, `ms`, `me`, `start`, `end`, `rounded-s`, `rounded-e`) over physical left/right utilities.
|
|
- Prefer `border` for lines and separators.
|
|
- Avoid `!important`; if unavoidable, keep the selector narrow and document why.
|
|
|
|
## JavaScript
|
|
- JavaScript is behavior only; do not use JS to paper over CSS architecture issues.
|
|
- Register JS components with `window.basecoat.register()` and make initialization idempotent with `data-*-initialized` flags.
|
|
- Component init functions must return before attaching listeners or mutating DOM when the root already has its initialized flag.
|
|
- Keep generated DOM minimal and aligned with documented HTML.
|
|
- Prefer native browser APIs and events.
|
|
- Keep scroll management scoped to component containers. Do not use `scrollIntoView()` when it can scroll the page unexpectedly.
|
|
- Emit custom events only for meaningful integration points.
|
|
|
|
## Upstream Migration
|
|
- Always check the upstream shadcn/ui repo before changing a migrated component: `https://github.com/shadcn-ui/ui`.
|
|
- Use a local copy of the upstream repo for migration work.
|
|
- Review these upstream repo paths:
|
|
- components: `apps/v4/registry/bases/base/ui/`
|
|
- docs: `apps/v4/content/docs/components/`
|
|
- examples: `apps/v4/registry/bases/base/examples/`
|
|
- styles: `apps/v4/registry/styles/style-{vega,nova,maia,lyra,mira,luma,sera,rhea}.css`
|
|
- Review Basecoat files in the same pass:
|
|
- component CSS: `src/css/components/<component>.css`
|
|
- style packs: `src/css/styles/{vega,nova,maia,lyra,mira,luma,sera,rhea}.css`
|
|
- JS: `src/js/<component>.js` when behavior changes
|
|
- templates: `src/templates/nunjucks/*.njk` and `src/templates/jinja/*.html.jinja` when markup changes
|
|
- docs: `site/src/docs/components/<component>.mdx`
|
|
- Map upstream concepts, not implementation details. Do not port `cn-*` selectors directly.
|
|
- Classify differences as `drift fixed`, `intentional`, or `deferred`.
|
|
|
|
## Docs
|
|
- Docs are Basecoat API docs, not React docs.
|
|
- Update docs when supported markup, variants, states, JS behavior, templates, or macros change.
|
|
- Prefer concrete HTML examples over abstract composition trees.
|
|
- Do not include React-only APIs such as `asChild`.
|
|
- Do not add "Composition" sections unless they describe stable Basecoat markup.
|
|
- Do not add API Reference sections for native/CSS-only components unless there is a real Basecoat API.
|
|
- Structure component docs as: title and preview, `## Usage`, optional `### HTML structure` for stable markup requirements, optional `### JavaScript API` for components with Basecoat JS methods/events/options, then `## Examples`.
|
|
- Keep `Usage` focused on the minimal working snippet and important Basecoat/upstream differences; put variants, states, RTL, and richer patterns under `Examples`.
|
|
- Keep snippets minimal and aligned with current behavior.
|
|
- In HTML snippets, keep text-only elements on one line, such as `<p>Text</p>`; use multiline formatting when the element contains child elements or when line length would hurt readability.
|
|
- In HTML examples, keep icons as single-line `<svg ...>...</svg>` elements, keep simple text-only or inline-formatting elements on one line, and avoid blank separator lines between adjacent markup parts.
|
|
- Document intentional differences from upstream near the relevant example.
|
|
|
|
## Validation
|
|
- Run `npm run build` after source/package changes.
|
|
- Run `npm run docs:build` after docs or docs asset changes.
|
|
- Manually verify changed components in docs across light/dark mode, style packs, variants, RTL when supported, and relevant interaction states.
|
|
|
|
## Change Management
|
|
- Ask before removing intentional functionality or public API.
|
|
- Preserve backward compatibility when the repo already depends on it, especially package exports and default `basecoat.css` behavior.
|
|
- Keep generated outputs and docs consistent with source changes.
|
|
- Remove stale comments/docs during refactors.
|
|
- Keep commits focused and imperative.
|
|
- Keep release-visible changes in `CHANGELOG.md` under `## [Unreleased]`; put backlog or incomplete work in `TODO.md` or the migration tracker.
|