cotomy 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,7 +50,8 @@ The View layer provides thin wrappers around DOM elements and window events.
50
50
  - Identity & matching
51
51
  - `instanceId: string` — Always returns the element's `data-cotomy-instance` (generated when missing, respects existing values)
52
52
  - `id: string | null | undefined`
53
- - `attached: boolean` — True when the element is connected to a document
53
+ - `attached: boolean` — True when the element belongs to the current window document
54
+ - `isConnected: boolean` — True when the element is connected to any document tree (Node.isConnected)
54
55
  - `generateId(prefix = "__cotomy_elem__"): this`
55
56
  - `is(selector: string): boolean` — Parent-aware matching helper
56
57
  - `empty: boolean` — True for tags that cannot have children or have no content
@@ -242,7 +243,7 @@ The Form layer builds on `CotomyElement` for common form flows.
242
243
  - `loadActionUrl: string` — Defaults to `actionUrl`; override or set for custom endpoints
243
244
  - `canLoad: boolean` — Defaults to `hasEntityKey`
244
245
  - Naming & binding
245
- - `bindNameGenerator(): ICotomyBindNameGenerator` — Defaults to `CotomyBracketBindNameGenerator` (`user[name]`)
246
+ - `bindNameGenerator(): ICotomyBindNameGenerator` — Defaults to `CotomyViewRenderer.defaultBindNameGenerator` (initial value: `CotomyBracketBindNameGenerator`, `user[name]`)
246
247
  - `renderer(): CotomyViewRenderer` — Applies `[data-cotomy-bind]` to view elements
247
248
  - `filler(type, (input, value))` — Register fillers; defaults provided for `datetime-local`, `checkbox`, `radio`
248
249
  - Fills non-array, non-object fields by matching input/select/textarea `name`
@@ -261,8 +262,7 @@ Example:
261
262
 
262
263
  ```ts
263
264
  const view = new CotomyViewRenderer(
264
- new CotomyElement(document.querySelector("#profile")!),
265
- new CotomyBracketBindNameGenerator()
265
+ new CotomyElement(document.querySelector("#profile")!)
266
266
  );
267
267
 
268
268
  await view.applyAsync(apiResponse); // apiResponse is CotomyApiResponse from CotomyApi
@@ -288,6 +288,24 @@ form.apiFailed(e => console.error("API failed", e.response.status));
288
288
  form.submitFailed(e => console.warn("Submit failed", e.response.status));
289
289
  ```
290
290
 
291
+ To switch the default bind naming style for a page, set it from your page controller:
292
+
293
+ ```ts
294
+ import {
295
+ CotomyDotBindNameGenerator,
296
+ CotomyEntityFillApiForm,
297
+ CotomyPageController
298
+ } from "cotomy";
299
+
300
+ CotomyPageController.set(class extends CotomyPageController {
301
+ protected override async initializeAsync(): Promise<void> {
302
+ this.defaultBindNameGenerator = new CotomyDotBindNameGenerator();
303
+
304
+ this.setForm(CotomyEntityFillApiForm.byId("profile-form", CotomyEntityFillApiForm)!);
305
+ }
306
+ });
307
+ ```
308
+
291
309
  ### Entity API forms
292
310
 
293
311
  `CotomyEntityApiForm` targets REST endpoints that identify records with a single surrogate key.
@@ -1113,6 +1113,9 @@ class CotomyElement {
1113
1113
  || this._element.innerHTML.trim() === "";
1114
1114
  }
1115
1115
  get attached() {
1116
+ return document.contains(this.element);
1117
+ }
1118
+ get isConnected() {
1116
1119
  return this.element.isConnected;
1117
1120
  }
1118
1121
  get readonly() {
@@ -2448,8 +2451,28 @@ class CotomyDotBindNameGenerator {
2448
2451
  return parent ? `${parent}[${index}]` : `[${index}]`;
2449
2452
  }
2450
2453
  }
2454
+ class CotomyBindNameGeneratorProvider {
2455
+ static getDefault() {
2456
+ return this._default ?? (this._default = new CotomyBracketBindNameGenerator());
2457
+ }
2458
+ static setDefault(generator) {
2459
+ this._default = generator;
2460
+ }
2461
+ static resetDefault() {
2462
+ this._default = undefined;
2463
+ }
2464
+ }
2451
2465
  class CotomyViewRenderer {
2452
- constructor(element, bindNameGenerator) {
2466
+ static get defaultBindNameGenerator() {
2467
+ return CotomyBindNameGeneratorProvider.getDefault();
2468
+ }
2469
+ static set defaultBindNameGenerator(generator) {
2470
+ CotomyBindNameGeneratorProvider.setDefault(generator);
2471
+ }
2472
+ static resetDefaultBindNameGenerator() {
2473
+ CotomyBindNameGeneratorProvider.resetDefault();
2474
+ }
2475
+ constructor(element, bindNameGenerator = CotomyViewRenderer.defaultBindNameGenerator) {
2453
2476
  this.element = element;
2454
2477
  this.bindNameGenerator = bindNameGenerator;
2455
2478
  this._renderers = {};
@@ -3045,7 +3068,7 @@ class CotomyEntityFillApiForm extends CotomyEntityApiForm {
3045
3068
  return this.actionUrl;
3046
3069
  }
3047
3070
  bindNameGenerator() {
3048
- return new CotomyBracketBindNameGenerator();
3071
+ return CotomyViewRenderer.defaultBindNameGenerator;
3049
3072
  }
3050
3073
  renderer() {
3051
3074
  return new CotomyViewRenderer(this, this.bindNameGenerator());
@@ -3149,6 +3172,7 @@ var utc_default = /*#__PURE__*/__webpack_require__.n(utc);
3149
3172
 
3150
3173
 
3151
3174
 
3175
+
3152
3176
  dayjs_min_default().extend((utc_default()));
3153
3177
  dayjs_min_default().extend((timezone_default()));
3154
3178
  class CotomyUrl {
@@ -3210,6 +3234,12 @@ class CotomyPageController {
3210
3234
  }
3211
3235
  return this._instance;
3212
3236
  }
3237
+ get defaultBindNameGenerator() {
3238
+ return CotomyViewRenderer.defaultBindNameGenerator;
3239
+ }
3240
+ set defaultBindNameGenerator(value) {
3241
+ CotomyViewRenderer.defaultBindNameGenerator = value;
3242
+ }
3213
3243
  setForm(form) {
3214
3244
  if (!form.id) {
3215
3245
  form.generateId();