ui-primitive-shape
A folder primitive must ship its proof siblings; a flat primitive must carry none at the ui root.
Runs under: @noctcore/harness lint-meta, not ESLint · Factory: createUiPrimitiveShapeRule from @noctcore/lint-meta-rules · Category: source-text · Fails CI by default: yes
The primitives root is the one place exempt from folder-per-component: flat single files are fine for presentational primitives. But once a primitive graduates to its own folder, it is a real component and must carry the same proof-of-behavior siblings (a test, a story) as any feature component. This closes the “the ui folder mixes two shapes with no rule” gap: flat = pure presentational; folder = tested + storied.
What it flags
Section titled “What it flags”- Folder primitives — for each
<uiRoot>/<Name>/<barrelFile>, each configured role must exist as<Name>.<role><extension>; a missing one is flagged. - Flat primitives — a flat
<uiRoot>/<Name><extension>(capitalized) that already has a sibling<Name>.<role><extension>at the ui root is flagged: those proof files belong inside a<Name>/folder.
What it does not flag
Section titled “What it does not flag”- A bare flat primitive (
<uiRoot>/Button.tsx) with no proof sibling at the ui root. - A folder primitive that ships every configured role (
Dialog/Dialog.test.tsx,Dialog/Dialog.stories.tsx). - A folder without the
barrelFile, and flat files whose name does not start with a capital letter. - Anything outside
uiRoot.
Options
Section titled “Options”createUiPrimitiveShapeRule(options?: UiPrimitiveShapeOptions): IMetaRule| Option | Type | Default | Meaning |
|---|---|---|---|
uiRoot |
string |
'apps/web/src/components/ui' |
The primitives root. |
barrelFile |
string |
'index.ts' |
Barrel file that marks a folder-primitive. |
roles |
string[] |
['test', 'stories'] |
Proof-of-behavior sibling roles a folder-primitive must ship. |
extension |
string |
'.tsx' |
Extension of primitive and proof files. |
ciCritical |
boolean |
true |
Whether a violation fails CI. |
When not to use it
Section titled “When not to use it”If you do not maintain a flat-vs-folder primitive convention or do not colocate stories/tests, skip the rule.