@cossackframework/renderer 0.6.0 → 0.7.0

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
@@ -209,6 +209,141 @@ import { live } from '@cossackframework/renderer';
209
209
  html`<input .value="${live(inputValue)}" />`
210
210
  ```
211
211
 
212
+ ### `bind`
213
+
214
+ Two-way binding for a form element's value/checked against a component state
215
+ field. It reads the field for rendering and writes user edits back to it. The
216
+ DOM property is inferred from the attribute it is attached to (`.value` →
217
+ `value`, `.checked` → `checked`).
218
+
219
+ ```typescript
220
+ import { bind } from '@cossackframework/renderer';
221
+
222
+ html`<input .value="${bind(this, 'email')}" />`
223
+ html`<input type="checkbox" .checked="${bind(this, 'active')}" />`
224
+ ```
225
+
226
+ `bind` supports dot-paths into nested state, so a `@Store` field can be bound at
227
+ any depth: `bind(this, 'address.street')`.
228
+
229
+ ### `key`
230
+
231
+ Force a subtree to be recreated when the key changes. Useful for re-triggering
232
+ CSS animations or remounting a child.
233
+
234
+ ```typescript
235
+ import { key } from '@cossackframework/renderer';
236
+
237
+ html`<div>${key(currentIndex, html`<div class="animate-fade-in">${child}</div>`)}</div>`
238
+ ```
239
+
240
+ ### `preventDefault`
241
+
242
+ Wraps an event handler so the event's default is prevented before it runs. It
243
+ also disables the browser's native validation on the bound `<form>` by default;
244
+ pass `{ novalidate: false }` to keep native validation.
245
+
246
+ ```typescript
247
+ import { preventDefault } from '@cossackframework/renderer';
248
+
249
+ html`<form @submit="${preventDefault(this.onSave)}"></form>`
250
+ html`<form @submit="${preventDefault(this.onSave, { novalidate: false })}"></form>`
251
+ ```
252
+
253
+ ### `when`
254
+
255
+ Render one of two templates based on a condition. Pass the truthy case and an
256
+ optional falsy case (both functions receive the condition).
257
+
258
+ ```typescript
259
+ import { when } from '@cossackframework/renderer';
260
+
261
+ html`${when(isOn, () => html`<p>On</p>`, () => html`<p>Off</p>`)}`
262
+ ```
263
+
264
+ ### `choose`
265
+
266
+ Select a template by matching a value against an ordered list of cases, like a
267
+ `switch`.
268
+
269
+ ```typescript
270
+ import { choose } from '@cossackframework/renderer';
271
+
272
+ html`${choose(status, [
273
+ ['idle', () => html`<i>Idle</i>`],
274
+ ['loading', () => html`<b>Loading…</b>`],
275
+ ], () => html`<span>Unknown</span>`)}`
276
+ ```
277
+
278
+ ### `ifDefined`
279
+
280
+ Only omit an attribute when the value is `undefined`; render every other value
281
+ (including `null`, `false`, `0`, `''`) as a normal attribute.
282
+
283
+ ```typescript
284
+ import { ifDefined } from '@cossackframework/renderer';
285
+
286
+ html`<a href="${ifDefined(url)}">link</a>`
287
+ ```
288
+
289
+ ### `guard`
290
+
291
+ Defer re-evaluating a template until its dependencies change. Wrap expensive
292
+ rendering so it is not recomputed on every render, only when the inputs it
293
+ depends on change. Pass a single dependency or an array (compared shallowly).
294
+
295
+ ```typescript
296
+ import { guard } from '@cossackframework/renderer';
297
+
298
+ html`<ul>${guard(items, () => html`...expensive...`)}</ul>`
299
+ html`${guard([query, page], () => renderResults(query, page))}`
300
+ ```
301
+
302
+ ### `cache`
303
+
304
+ Keep previously-rendered template subtrees alive instead of destroying them
305
+ when the rendered value switches templates. Toggling back to a cached template
306
+ reattaches its existing DOM and part tree, preserving component state, scroll
307
+ position, and focus.
308
+
309
+ ```typescript
310
+ import { cache } from '@cossackframework/renderer';
311
+
312
+ html`${cache(showA ? html`<a-component></a-component>` : html`<b-component></b-component>`)}`
313
+ ```
314
+
315
+ ### `map`
316
+
317
+ Map an iterable to renderable values and render them as a list.
318
+
319
+ ```typescript
320
+ import { map } from '@cossackframework/renderer';
321
+
322
+ html`<ul>${map(items, (item) => html`<li>${item.name}</li>`)}</ul>`
323
+ ```
324
+
325
+ ### `join`
326
+
327
+ Join renderable values with a separator interleaved between each pair. The
328
+ separator can be a static value or a template (e.g. a divider element).
329
+
330
+ ```typescript
331
+ import { join } from '@cossackframework/renderer';
332
+
333
+ html`${join(names, (n) => n, ', ')}` // "a, b, c"
334
+ html`<ul>${join(items, (i) => html`<li>${i}</li>`, () => html`<li class="sep">•</li>`)}</ul>`
335
+ ```
336
+
337
+ ### `range`
338
+
339
+ Generate an increasing (or decreasing) sequence of numbers as an array.
340
+
341
+ ```typescript
342
+ import { range } from '@cossackframework/renderer';
343
+
344
+ html`<ul>${range(0, 5).map((n) => html`<li>${n}</li>`)}</ul>` // 0..4
345
+ ```
346
+
212
347
  ## Context API
213
348
 
214
349
  Share state deep in the tree.
@@ -1,5 +1,4 @@
1
1
  import { CossackElement } from './cossack-element';
2
-
3
2
  export interface ComponentResult {
4
3
  _type: 'COMPONENT';
5
4
  clazz: new () => CossackElement;
@@ -1,6 +1,5 @@
1
1
  import { TemplateResult } from './cossack-html';
2
2
  import { Context } from './context';
3
-
4
3
  export type PropertyDeclaration = {
5
4
  type?: unknown;
6
5
  reflect?: boolean;
@@ -57,7 +56,7 @@ export declare class CossackElement implements ReactiveControllerHost {
57
56
  private __notifyListeners;
58
57
  addRenderListener(listener: (template: TemplateResult | unknown | null) => void): void;
59
58
  removeRenderListener(listener: (template: TemplateResult | unknown | null) => void): void;
60
- mount(container: HTMLElement): void;
59
+ mount(container: HTMLElement, hydrateFirst?: boolean): void;
61
60
  addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, _options?: boolean | AddEventListenerOptions): void;
62
61
  removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, _options?: boolean | EventListenerOptions): void;
63
62
  dispatchEvent(event: Event): boolean;