# XWUICRUD

The abstract, headless base that every single-domain "master" component extends to inherit the canonical five-state CRUD machine - `create` | `read` | `update` | `delete` | `json`. It owns no DOM beyond one root `div` (class set by the subclass via `getRootClassName()`) and a dispatch table (`renderActivePanel()`) that routes the active state to one of five abstract render hooks the subclass must implement: `renderCreate` / `renderRead` / `renderUpdate` / `renderDelete` / `renderJson`. State is exposed as `setState(next)` so a parent (e.g. `XWUIEntityMaster`) can drive the active panel without the sub-master rendering its own tab strip; `getState()`, `isStateEnabled()`, and `getEnabledStates()` round out the contract, with `config.enabledStates` hiding states and falling back to the first enabled one. The base intentionally does NOT auto-render - subclasses call `super(...)`, do their own setup (load manifests, normalize data), then call `buildRoot()` + `render()`. Concrete subclasses include `XWUIListMaster` (and its `XWUIListEntityMaster` / `XWUIListRecordMaster`), `XWUIFormEditorMaster`, and `XWUIRecordMaster`.

## Usage

XWUICRUD is abstract - you subclass it rather than instantiate it directly. A minimal subclass implements the five render hooks and a root class name:

```ts
import { XWUICRUD, type CRUDData, type CRUDConfig } from './XWUICRUD';

class MyMaster extends XWUICRUD<CRUDData, CRUDConfig> {
  static componentName = 'MyMaster';
  protected getRootClassName(): string { return 'my-master'; }
  protected renderRead(host: HTMLElement): void   { host.textContent = 'read';   }
  protected renderCreate(host: HTMLElement): void { host.textContent = 'create'; }
  protected renderUpdate(host: HTMLElement): void { host.textContent = 'update'; }
  protected renderDelete(host: HTMLElement): void { host.textContent = 'delete'; }
  protected renderJson(host: HTMLElement): void   { host.textContent = 'json';   }
  constructor(container: HTMLElement, data: CRUDData, conf: CRUDConfig = {}) {
    super(container, data, conf);
    this.buildRoot();   // base does NOT auto-render
    this.render();
  }
}

const master = new MyMaster(document.getElementById('app')!, { state: 'read' }, { initialState: 'read' });
master.setState('update');
```

```api
```
