Aman-Mittal opened a new issue, #684:
URL: https://github.com/apache/fineract-backoffice-ui/issues/684
`local/no-vendor-ui-import` has been stuck at **227 files** for a while, and
measuring why turns up something worth acting on before anyone spends another
PR on it.
`src/app/ui/` currently holds six primitives: `button`, `icon`, `spinner`,
`searchable-select`, `deferred-datetime-button`, `tabs`. Those cover the four
most-imported Ionic components in the codebase — `IonButton` appears in 214 of
the 227 files. And yet:
| primitives available | files that fully clear |
| --- | --- |
| what exists today | **17** |
| + a card set (`IonCard`/`CardHeader`/`CardTitle`/`CardContent`) | 28 |
| + a form-field set (`IonItem`/`Label`/`Input`/`Textarea`/`Checkbox`) | 45 |
| **+ both sets together** | **172** |
| + a layout set (`IonGrid`/`Row`/`Col`/`List`) | 189 |
## Why the jump
A file clears only when **every** Ionic import in it is covered — the rule
reports the import statement, not the symbol. And these files are not small: of
the 227, most import nine to fifteen distinct Ionic components.
```
9 component(s): 25 files 12 component(s): 25 files
10 component(s): 18 files 13 component(s): 11 files
11 component(s): 23 files 14 component(s): 17 files
```
A typical screen is a card wrapping a form. Shipping the card set alone
leaves every one of those files importing `IonItem` and `IonInput`; shipping
the form set alone leaves them importing `IonCard`. Either half on its own
clears a handful. Together they clear 172 — **76% of the backlog**.
This is also why a greedy "which primitive clears the most files" search is
misleading here. It reports `+5, +2, +1…` and makes the work look like a long
grind of unrewarding steps, when in fact almost all the value sits behind two
clusters that have to land before anything moves.
## Suggested shape
Build the primitives in one PR (or a short series that is merged together),
then migrate screens in small batches afterwards. The migration batches are the
easy, reviewable part; it is the primitive set that is the design work.
Worth deciding deliberately rather than by accident:
- **`IonItem` + `IonLabel` + `IonInput` is one primitive, not three.** Every
form field in this codebase is that trio plus `fill="outline"` and
`position="stacked"`. A field primitive that owns the trio is what removes the
per-screen repetition; three thin wrappers would keep it.
- **Accessible names are part of the contract.**
`scripts/check-a11y-names.mjs` exists because these controls kept shipping
without one. A primitive that takes a label and wires `[attr.aria-label]`
itself makes that check redundant rather than adversarial.
- **Keep the imperative boundary separate.** `ModalController` and friends
are ADR 0003's surface, reached through `OVERLAY`, and `no-vendor-ui-import`
deliberately exempts an import of nothing but controllers so that one import
statement sits on one boundary. Eight files in this set still import
`ModalController`; those go through `OVERLAY`, not through a new primitive.
## After both sets
The long tail is genuinely small, and `IonSegment`/`IonSegmentButton` is
most of it:
```
15 IonSegment 9 IonPopover 5 IonChip
15 IonSegmentButton 5 IonSearchbar 4 IonBadge
```
Note `tabs` already exists as a primitive — the 15 `IonSegment` files are
worth a look to see whether they want it rather than a new one.
## Acceptance
- The card and form-field primitives live in `src/app/ui/`, with specs, and
are added to the `VENDOR_UI_ALLOWED` list in `eslint.config.js`.
- `npm run check:ui-primitives` passes.
- Screen migrations land as separate small PRs, each dropping the files it
touches from `eslint-suppressions.json` via `npm run lint:prune`.
Background: `DOCS/adr/0005-ui-component-boundary.md`, `AGENTS.md`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]