clapton 0.0.16 → 0.0.18

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -8
  3. data/lib/clapton/engine.rb +1 -1
  4. data/lib/clapton/javascripts/dist/client.js +12 -4
  5. data/lib/clapton/javascripts/dist/components-for-test.js +49 -45
  6. data/lib/clapton/javascripts/dist/components.js +49 -45
  7. data/lib/clapton/javascripts/src/channel/clapton-channel.js +1 -1
  8. data/lib/clapton/javascripts/src/client.ts +9 -2
  9. data/lib/clapton/javascripts/src/components/block-quote.spec.ts +6 -6
  10. data/lib/clapton/javascripts/src/components/block-quote.ts +2 -2
  11. data/lib/clapton/javascripts/src/components/bold.spec.ts +3 -3
  12. data/lib/clapton/javascripts/src/components/bold.ts +2 -2
  13. data/lib/clapton/javascripts/src/components/box.spec.ts +6 -6
  14. data/lib/clapton/javascripts/src/components/box.ts +2 -2
  15. data/lib/clapton/javascripts/src/components/button.spec.ts +5 -5
  16. data/lib/clapton/javascripts/src/components/button.ts +2 -2
  17. data/lib/clapton/javascripts/src/components/checkbox.spec.ts +3 -3
  18. data/lib/clapton/javascripts/src/components/checkbox.ts +1 -1
  19. data/lib/clapton/javascripts/src/components/code.spec.ts +6 -6
  20. data/lib/clapton/javascripts/src/components/code.ts +2 -2
  21. data/lib/clapton/javascripts/src/components/component.ts +8 -4
  22. data/lib/clapton/javascripts/src/components/datetime-field.spec.ts +3 -3
  23. data/lib/clapton/javascripts/src/components/datetime-field.ts +1 -1
  24. data/lib/clapton/javascripts/src/components/element.spec.ts +6 -6
  25. data/lib/clapton/javascripts/src/components/element.ts +2 -2
  26. data/lib/clapton/javascripts/src/components/embed.spec.ts +1 -1
  27. data/lib/clapton/javascripts/src/components/embed.ts +1 -1
  28. data/lib/clapton/javascripts/src/components/emphasis.spec.ts +6 -6
  29. data/lib/clapton/javascripts/src/components/emphasis.ts +2 -2
  30. data/lib/clapton/javascripts/src/components/form.spec.ts +6 -6
  31. data/lib/clapton/javascripts/src/components/form.ts +2 -2
  32. data/lib/clapton/javascripts/src/components/heading.spec.ts +6 -6
  33. data/lib/clapton/javascripts/src/components/heading.ts +2 -2
  34. data/lib/clapton/javascripts/src/components/image.spec.ts +2 -2
  35. data/lib/clapton/javascripts/src/components/image.ts +1 -1
  36. data/lib/clapton/javascripts/src/components/link.spec.ts +6 -6
  37. data/lib/clapton/javascripts/src/components/link.ts +2 -2
  38. data/lib/clapton/javascripts/src/components/list-item.spec.ts +6 -6
  39. data/lib/clapton/javascripts/src/components/list-item.ts +2 -2
  40. data/lib/clapton/javascripts/src/components/list.spec.ts +6 -6
  41. data/lib/clapton/javascripts/src/components/list.ts +2 -2
  42. data/lib/clapton/javascripts/src/components/ordered-list.spec.ts +6 -6
  43. data/lib/clapton/javascripts/src/components/ordered-list.ts +2 -2
  44. data/lib/clapton/javascripts/src/components/paragraph.spec.ts +6 -6
  45. data/lib/clapton/javascripts/src/components/paragraph.ts +2 -2
  46. data/lib/clapton/javascripts/src/components/presets.ts +1 -1
  47. data/lib/clapton/javascripts/src/components/quote.spec.ts +6 -6
  48. data/lib/clapton/javascripts/src/components/quote.ts +2 -2
  49. data/lib/clapton/javascripts/src/components/radio-button.spec.ts +3 -3
  50. data/lib/clapton/javascripts/src/components/radio-button.ts +1 -1
  51. data/lib/clapton/javascripts/src/components/select.spec.ts +6 -6
  52. data/lib/clapton/javascripts/src/components/select.ts +2 -2
  53. data/lib/clapton/javascripts/src/components/span.spec.ts +6 -6
  54. data/lib/clapton/javascripts/src/components/span.ts +2 -2
  55. data/lib/clapton/javascripts/src/components/text-area.spec.ts +3 -3
  56. data/lib/clapton/javascripts/src/components/text-area.ts +1 -1
  57. data/lib/clapton/javascripts/src/components/text-field.spec.ts +3 -3
  58. data/lib/clapton/javascripts/src/components/text-field.ts +1 -1
  59. data/lib/clapton/javascripts/src/components/text.spec.ts +2 -2
  60. data/lib/clapton/javascripts/src/components/text.ts +1 -1
  61. data/lib/clapton/javascripts/src/dom/update-component.ts +1 -1
  62. data/lib/clapton/test_helper/base.rb +2 -2
  63. data/lib/clapton/version.rb +2 -1
  64. data/lib/rails/generators/clapton_generator.rb +2 -0
  65. metadata +1 -1
@@ -45,8 +45,8 @@ class BlockQuote {
45
45
  this.children = [];
46
46
  this.attributes = attributes;
47
47
  }
48
- get render() {
49
- return `<blockquote ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</blockquote>`;
48
+ get renderWrapper() {
49
+ return `<blockquote ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</blockquote>`;
50
50
  }
51
51
  add(child) {
52
52
  this.children.push(child);
@@ -63,8 +63,8 @@ class Box {
63
63
  this.children.push(child);
64
64
  return this;
65
65
  }
66
- get render() {
67
- return `<div ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</div>`;
66
+ get renderWrapper() {
67
+ return `<div ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</div>`;
68
68
  }
69
69
  add_action(eventType, stateName, fnName, options = {}) {
70
70
  this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${eventType}->${stateName}#${fnName}@${options.debounce || 0}`;
@@ -81,8 +81,8 @@ class Button {
81
81
  this.children.push(child);
82
82
  return this;
83
83
  }
84
- get render() {
85
- return `<button ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</button>`;
84
+ get renderWrapper() {
85
+ return `<button ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</button>`;
86
86
  }
87
87
  add_action(event, klass, fn, options = {}) {
88
88
  this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
@@ -95,8 +95,8 @@ class Bold {
95
95
  this.children = [];
96
96
  this.attributes = attributes;
97
97
  }
98
- get render() {
99
- return `<strong ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</strong>`;
98
+ get renderWrapper() {
99
+ return `<strong ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</strong>`;
100
100
  }
101
101
  add(child) {
102
102
  this.children.push(child);
@@ -111,7 +111,7 @@ class Checkbox {
111
111
  this.attribute = attribute;
112
112
  this.attributes["data-attribute"] = attribute;
113
113
  }
114
- get render() {
114
+ get renderWrapper() {
115
115
  return `<input type='checkbox' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
116
116
  }
117
117
  add_action(event, klass, fn, options = {}) {
@@ -125,8 +125,8 @@ class Code {
125
125
  this.children = [];
126
126
  this.attributes = attributes;
127
127
  }
128
- get render() {
129
- return `<code ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</code>`;
128
+ get renderWrapper() {
129
+ return `<code ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</code>`;
130
130
  }
131
131
  add(child) {
132
132
  this.children.push(child);
@@ -142,7 +142,7 @@ class DateTimeField {
142
142
  this.attributes = attributes;
143
143
  this.attributes["data-attribute"] = attribute;
144
144
  }
145
- get render() {
145
+ get renderWrapper() {
146
146
  const value = this.state[this.attribute] ? this.datetime_local_value(this.state[this.attribute]) : "";
147
147
  return `<input type='datetime-local' ${htmlAttributes(this.attributes)} value='${value}'/>`;
148
148
  }
@@ -182,8 +182,8 @@ class Element {
182
182
  this.type = type;
183
183
  this.attributes = attributes;
184
184
  }
185
- get render() {
186
- return `<${this.type} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</${this.type}>`;
185
+ get renderWrapper() {
186
+ return `<${this.type} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</${this.type}>`;
187
187
  }
188
188
  add(child) {
189
189
  this.children.push(child);
@@ -195,7 +195,7 @@ class Embed {
195
195
  constructor(html) {
196
196
  this.html = html;
197
197
  }
198
- get render() {
198
+ get renderWrapper() {
199
199
  return this.html;
200
200
  }
201
201
  }
@@ -205,8 +205,8 @@ class Emphasis {
205
205
  this.children = [];
206
206
  this.attributes = attributes;
207
207
  }
208
- get render() {
209
- return `<em ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</em>`;
208
+ get renderWrapper() {
209
+ return `<em ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</em>`;
210
210
  }
211
211
  add(child) {
212
212
  this.children.push(child);
@@ -219,8 +219,8 @@ class Form {
219
219
  this.children = [];
220
220
  this.attributes = attributes;
221
221
  }
222
- get render() {
223
- return `<form ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</form>`;
222
+ get renderWrapper() {
223
+ return `<form ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</form>`;
224
224
  }
225
225
  add(child) {
226
226
  this.children.push(child);
@@ -234,8 +234,8 @@ class Heading {
234
234
  this.level = level;
235
235
  this.attributes = attributes;
236
236
  }
237
- get render() {
238
- return `<h${this.level} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</h${this.level}>`;
237
+ get renderWrapper() {
238
+ return `<h${this.level} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</h${this.level}>`;
239
239
  }
240
240
  add(child) {
241
241
  this.children.push(child);
@@ -250,7 +250,7 @@ class Image {
250
250
  this.src = src;
251
251
  this.alt = alt;
252
252
  }
253
- get render() {
253
+ get renderWrapper() {
254
254
  return `<img src='${this.src}' alt='${this.alt}' ${htmlAttributes(this.attributes)}/>`;
255
255
  }
256
256
  }
@@ -261,8 +261,8 @@ class Link {
261
261
  this.attributes = attributes;
262
262
  this.href = href;
263
263
  }
264
- get render() {
265
- return `<a href='${this.href}' ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</a>`;
264
+ get renderWrapper() {
265
+ return `<a href='${this.href}' ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</a>`;
266
266
  }
267
267
  add(child) {
268
268
  this.children.push(child);
@@ -279,8 +279,8 @@ class ListItem {
279
279
  this.children.push(child);
280
280
  return this;
281
281
  }
282
- get render() {
283
- return `<li ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</li>`;
282
+ get renderWrapper() {
283
+ return `<li ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</li>`;
284
284
  }
285
285
  }
286
286
 
@@ -293,8 +293,8 @@ class List {
293
293
  this.children.push(child);
294
294
  return this;
295
295
  }
296
- get render() {
297
- return `<ul ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</ul>`;
296
+ get renderWrapper() {
297
+ return `<ul ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</ul>`;
298
298
  }
299
299
  }
300
300
 
@@ -307,8 +307,8 @@ class OrderedList {
307
307
  this.children.push(child);
308
308
  return this;
309
309
  }
310
- get render() {
311
- return `<ol ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</ol>`;
310
+ get renderWrapper() {
311
+ return `<ol ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</ol>`;
312
312
  }
313
313
  }
314
314
 
@@ -317,8 +317,8 @@ class Paragraph {
317
317
  this.children = [];
318
318
  this.attributes = attributes;
319
319
  }
320
- get render() {
321
- return `<p ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</p>`;
320
+ get renderWrapper() {
321
+ return `<p ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</p>`;
322
322
  }
323
323
  add(child) {
324
324
  this.children.push(child);
@@ -331,8 +331,8 @@ class Quote {
331
331
  this.children = [];
332
332
  this.attributes = attributes;
333
333
  }
334
- get render() {
335
- return `<q ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</q>`;
334
+ get renderWrapper() {
335
+ return `<q ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</q>`;
336
336
  }
337
337
  add(child) {
338
338
  this.children.push(child);
@@ -347,7 +347,7 @@ class RadioButton {
347
347
  this.attribute = attribute;
348
348
  this.attributes["data-attribute"] = attribute;
349
349
  }
350
- get render() {
350
+ get renderWrapper() {
351
351
  return `<input type='radio' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
352
352
  }
353
353
  add_action(event, klass, fn, options = {}) {
@@ -364,8 +364,8 @@ class Select {
364
364
  this.attribute = attribute;
365
365
  this.attributes = attributes;
366
366
  }
367
- get render() {
368
- return `<select ${htmlAttributes(this.attributes)}>${this.options.map(option => `<option value='${option.value}'${option.value === this.state[this.attribute] ? " selected" : ""}>${option.text}</option>`).join("")}${this.children.map(child => child.render).join("")}</select>`;
367
+ get renderWrapper() {
368
+ return `<select ${htmlAttributes(this.attributes)}>${this.options.map(option => `<option value='${option.value}'${option.value === this.state[this.attribute] ? " selected" : ""}>${option.text}</option>`).join("")}${this.children.map(child => child.renderWrapper).join("")}</select>`;
369
369
  }
370
370
  }
371
371
 
@@ -374,8 +374,8 @@ class Span {
374
374
  this.children = [];
375
375
  this.attributes = attributes;
376
376
  }
377
- get render() {
378
- return `<span ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</span>`;
377
+ get renderWrapper() {
378
+ return `<span ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</span>`;
379
379
  }
380
380
  add(child) {
381
381
  this.children.push(child);
@@ -421,7 +421,7 @@ class Presets {
421
421
  return new Clapton.Heading(props[0], props[1]);
422
422
  }
423
423
  img(...props) {
424
- return new Clapton.Image(props[0], props[1]);
424
+ return new Clapton.Image(props[0], props[1], props[2]);
425
425
  }
426
426
  a(...props) {
427
427
  return new Clapton.Link(props[0], props[1]);
@@ -466,11 +466,15 @@ class Component {
466
466
  this._state = state;
467
467
  this.id = id;
468
468
  this._errors = errors;
469
- this._root = new Box({ data: { component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } });
470
469
  this._c = new Presets();
471
470
  }
472
471
  get render() {
473
- return this._root.render;
472
+ return new Box({});
473
+ }
474
+ get renderWrapper() {
475
+ const root = this.render;
476
+ root.attributes = { ...root.attributes, data: { ...root.attributes.data, component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } };
477
+ return root.renderWrapper;
474
478
  }
475
479
  }
476
480
 
@@ -481,7 +485,7 @@ class TextField {
481
485
  this.attribute = attribute;
482
486
  this.attributes["data-attribute"] = attribute;
483
487
  }
484
- get render() {
488
+ get renderWrapper() {
485
489
  return `<input type='text' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
486
490
  }
487
491
  add_action(event, klass, fn, options = {}) {
@@ -494,7 +498,7 @@ class Text {
494
498
  constructor(value) {
495
499
  this.value = value;
496
500
  }
497
- get render() {
501
+ get renderWrapper() {
498
502
  return this.value;
499
503
  }
500
504
  }
@@ -506,7 +510,7 @@ class TextArea {
506
510
  this.attribute = attribute;
507
511
  this.attributes["data-attribute"] = attribute;
508
512
  }
509
- get render() {
513
+ get renderWrapper() {
510
514
  return `<textarea ${htmlAttributes(this.attributes)}>${this.state[this.attribute] || ""}</textarea>`;
511
515
  }
512
516
  add_action(event, klass, fn, options = {}) {
@@ -16,7 +16,7 @@ export const claptonChannel = consumer.subscriptions.create("Clapton::ClaptonCha
16
16
  const component = document.querySelector(`[data-id="${data.component.id}"]`)
17
17
  const module = await import(`${data.component.name}`);
18
18
  const instance = new module[data.component.name](data.state, data.component.id, errors);
19
- morphdom(component, instance.render, {
19
+ morphdom(component, instance.renderWrapper, {
20
20
  onBeforeElUpdated: (_fromEl, toEl) => {
21
21
  toEl.setAttribute("data-set-event-handler", "true");
22
22
  return true;
@@ -21,13 +21,20 @@ const initializeComponents = async () => {
21
21
  };
22
22
 
23
23
  const createAndAppendComponent = async (component: ComponentDefinition, element: HTMLElement) => {
24
+ if (!element) {
25
+ return;
26
+ }
24
27
  const componentDom = document.createElement('div');
25
28
  const module = await import(`${component.component}`);
26
29
  const instance = new (module[component.component] as any)(component.state);
27
- componentDom.innerHTML = instance.render;
30
+ componentDom.innerHTML = instance.renderWrapper;
28
31
  const firstChild = componentDom.firstChild as HTMLElement;
29
32
  if (firstChild) {
30
- element.appendChild(firstChild);
33
+ if (element.children.length > 0) {
34
+ element.appendChild(firstChild);
35
+ } else {
36
+ element.outerHTML = firstChild.outerHTML;
37
+ }
31
38
  }
32
39
  };
33
40
 
@@ -4,23 +4,23 @@ import { Text } from "./text"
4
4
 
5
5
  describe("BlockQuote", () => {
6
6
  it("returns empty string if no params", () => {
7
- expect(new BlockQuote().render).toBe("<blockquote ></blockquote>")
7
+ expect(new BlockQuote().renderWrapper).toBe("<blockquote ></blockquote>")
8
8
  })
9
9
 
10
10
  it("returns attributes and data attributes", () => {
11
- expect(new BlockQuote({ id: "1", "data-foo": "bar" }).render).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
11
+ expect(new BlockQuote({ id: "1", "data-foo": "bar" }).renderWrapper).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
12
12
  })
13
13
 
14
14
  it("returns attributes and data attributes with custom data attributes", () => {
15
- expect(new BlockQuote({ id: "1", data: { foo: "bar" } }).render).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
16
- expect(new BlockQuote({ id: "1", data: { foo: "bar", baz: "qux" } }).render).toBe(`<blockquote id='1' data-foo='bar' data-baz='qux'></blockquote>`)
17
- expect(new BlockQuote({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).render).toBe(`<blockquote id='1' data-foo-baz='qux' data-foo-quux='corge'></blockquote>`)
15
+ expect(new BlockQuote({ id: "1", data: { foo: "bar" } }).renderWrapper).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
16
+ expect(new BlockQuote({ id: "1", data: { foo: "bar", baz: "qux" } }).renderWrapper).toBe(`<blockquote id='1' data-foo='bar' data-baz='qux'></blockquote>`)
17
+ expect(new BlockQuote({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toBe(`<blockquote id='1' data-foo-baz='qux' data-foo-quux='corge'></blockquote>`)
18
18
  })
19
19
 
20
20
  it("adds children", () => {
21
21
  const text = new Text("Hello")
22
22
  const blockQuote = new BlockQuote()
23
23
  blockQuote.add(text)
24
- expect(blockQuote.render).toBe(`<blockquote >Hello</blockquote>`)
24
+ expect(blockQuote.renderWrapper).toBe(`<blockquote >Hello</blockquote>`)
25
25
  })
26
26
  })
@@ -9,8 +9,8 @@ export class BlockQuote {
9
9
  this.attributes = attributes;
10
10
  }
11
11
 
12
- get render(): string {
13
- return `<blockquote ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</blockquote>`;
12
+ get renderWrapper(): string {
13
+ return `<blockquote ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</blockquote>`;
14
14
  }
15
15
 
16
16
  add(child: any): BlockQuote {
@@ -4,11 +4,11 @@ import { Bold } from "./bold"
4
4
 
5
5
  describe("Bold", () => {
6
6
  it("returns empty string if no params", () => {
7
- expect(new Bold().render).toBe("<strong ></strong>")
7
+ expect(new Bold().renderWrapper).toBe("<strong ></strong>")
8
8
  })
9
9
 
10
10
  it("returns attributes and data attributes", () => {
11
- expect(new Bold({ id: "1", "data-foo": "bar" }).render).toBe(`<strong id='1' data-foo='bar'></strong>`)
11
+ expect(new Bold({ id: "1", "data-foo": "bar" }).renderWrapper).toBe(`<strong id='1' data-foo='bar'></strong>`)
12
12
  })
13
13
 
14
14
 
@@ -16,6 +16,6 @@ describe("Bold", () => {
16
16
  const text = new Text("Hello")
17
17
  const bold = new Bold()
18
18
  bold.add(text)
19
- expect(bold.render).toBe(`<strong >Hello</strong>`)
19
+ expect(bold.renderWrapper).toBe(`<strong >Hello</strong>`)
20
20
  })
21
21
  })
@@ -9,8 +9,8 @@ export class Bold {
9
9
  this.attributes = attributes;
10
10
  }
11
11
 
12
- get render(): string {
13
- return `<strong ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</strong>`;
12
+ get renderWrapper(): string {
13
+ return `<strong ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</strong>`;
14
14
  }
15
15
 
16
16
  add(child: any): Bold {
@@ -4,20 +4,20 @@ import { Text } from "./text"
4
4
 
5
5
  describe("Box", () => {
6
6
  it("returns empty string if no params", () => {
7
- expect(new Box().render).toBe("<div ></div>")
7
+ expect(new Box().renderWrapper).toBe("<div ></div>")
8
8
  })
9
9
 
10
10
  it("returns attributes and data attributes", () => {
11
- expect(new Box({ id: "1", "data-foo": "bar" }).render).toBe(`<div id='1' data-foo='bar'></div>`)
11
+ expect(new Box({ id: "1", "data-foo": "bar" }).renderWrapper).toBe(`<div id='1' data-foo='bar'></div>`)
12
12
  })
13
13
 
14
14
  it("returns attributes and data attributes with custom data attributes", () => {
15
- expect(new Box({ id: "1", data: { foo: "bar" } }).render).toBe(`<div id='1' data-foo='bar'></div>`)
16
- expect(new Box({ id: "1", data: { foo: "bar", baz: "qux" } }).render).toBe(`<div id='1' data-foo='bar' data-baz='qux'></div>`)
17
- expect(new Box({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).render).toBe(`<div id='1' data-foo-baz='qux' data-foo-quux='corge'></div>`)
15
+ expect(new Box({ id: "1", data: { foo: "bar" } }).renderWrapper).toBe(`<div id='1' data-foo='bar'></div>`)
16
+ expect(new Box({ id: "1", data: { foo: "bar", baz: "qux" } }).renderWrapper).toBe(`<div id='1' data-foo='bar' data-baz='qux'></div>`)
17
+ expect(new Box({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toBe(`<div id='1' data-foo-baz='qux' data-foo-quux='corge'></div>`)
18
18
  })
19
19
 
20
20
  it("adds children", () => {
21
- expect(new Box().add(new Text("Hello, world!")).render).toBe(`<div >Hello, world!</div>`)
21
+ expect(new Box().add(new Text("Hello, world!")).renderWrapper).toBe(`<div >Hello, world!</div>`)
22
22
  })
23
23
  })
@@ -14,8 +14,8 @@ export class Box {
14
14
  return this;
15
15
  }
16
16
 
17
- get render(): string {
18
- return `<div ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</div>`;
17
+ get renderWrapper(): string {
18
+ return `<div ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</div>`;
19
19
  }
20
20
 
21
21
  add_action(eventType: string, stateName: string, fnName: string, options: Record<string, any> = {}): this {
@@ -3,16 +3,16 @@ import { Button } from "./button"
3
3
 
4
4
  describe("Button", () => {
5
5
  it("returns empty string if no params", () => {
6
- expect(new Button().render).toBe("<button ></button>")
6
+ expect(new Button().renderWrapper).toBe("<button ></button>")
7
7
  })
8
8
 
9
9
  it("returns attributes and data attributes", () => {
10
- expect(new Button({ id: "1", "data-foo": "bar" }).render).toBe(`<button id='1' data-foo='bar'></button>`)
10
+ expect(new Button({ id: "1", "data-foo": "bar" }).renderWrapper).toBe(`<button id='1' data-foo='bar'></button>`)
11
11
  })
12
12
 
13
13
  it("returns attributes and data attributes with custom data attributes", () => {
14
- expect(new Button({ id: "1", data: { foo: "bar" } }).render).toBe(`<button id='1' data-foo='bar'></button>`)
15
- expect(new Button({ id: "1", data: { foo: "bar", baz: "qux" } }).render).toBe(`<button id='1' data-foo='bar' data-baz='qux'></button>`)
16
- expect(new Button({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).render).toBe(`<button id='1' data-foo-baz='qux' data-foo-quux='corge'></button>`)
14
+ expect(new Button({ id: "1", data: { foo: "bar" } }).renderWrapper).toBe(`<button id='1' data-foo='bar'></button>`)
15
+ expect(new Button({ id: "1", data: { foo: "bar", baz: "qux" } }).renderWrapper).toBe(`<button id='1' data-foo='bar' data-baz='qux'></button>`)
16
+ expect(new Button({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toBe(`<button id='1' data-foo-baz='qux' data-foo-quux='corge'></button>`)
17
17
  })
18
18
  })
@@ -14,8 +14,8 @@ export class Button {
14
14
  return this;
15
15
  }
16
16
 
17
- get render(): string {
18
- return `<button ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</button>`;
17
+ get renderWrapper(): string {
18
+ return `<button ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</button>`;
19
19
  }
20
20
 
21
21
  add_action(event: string, klass: string, fn: string, options: Record<string, any> = {}): Button {
@@ -3,14 +3,14 @@ import { Checkbox } from "./checkbox"
3
3
 
4
4
  describe("Checkbox", () => {
5
5
  it("returns empty string if no params", () => {
6
- expect(new Checkbox({}, "foo").render).toBe("<input type='checkbox' data-attribute='foo' value=''/>")
6
+ expect(new Checkbox({}, "foo").renderWrapper).toBe("<input type='checkbox' data-attribute='foo' value=''/>")
7
7
  })
8
8
 
9
9
  it("returns attributes and data attributes", () => {
10
- expect(new Checkbox({ foo: "bar" }, "foo", { id: "1", "data-foo": "bar" }).render).toBe(`<input type='checkbox' id='1' data-foo='bar' data-attribute='foo' value='bar'/>`)
10
+ expect(new Checkbox({ foo: "bar" }, "foo", { id: "1", "data-foo": "bar" }).renderWrapper).toBe(`<input type='checkbox' id='1' data-foo='bar' data-attribute='foo' value='bar'/>`)
11
11
  })
12
12
 
13
13
  it("returns attributes and data attributes with custom data attributes", () => {
14
- expect(new Checkbox({ foo: "bar" }, "foo", { id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).render).toBe(`<input type='checkbox' id='1' data-attribute='foo' data-foo-baz='qux' data-foo-quux='corge' value='bar'/>`)
14
+ expect(new Checkbox({ foo: "bar" }, "foo", { id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toBe(`<input type='checkbox' id='1' data-attribute='foo' data-foo-baz='qux' data-foo-quux='corge' value='bar'/>`)
15
15
  })
16
16
  })
@@ -12,7 +12,7 @@ export class Checkbox {
12
12
  this.attributes["data-attribute"] = attribute;
13
13
  }
14
14
 
15
- get render(): string {
15
+ get renderWrapper(): string {
16
16
  return `<input type='checkbox' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
17
17
  }
18
18
 
@@ -4,23 +4,23 @@ import { Text } from "./text"
4
4
 
5
5
  describe("Code", () => {
6
6
  it("returns empty string if no params", () => {
7
- expect(new Code().render).toBe("<code ></code>")
7
+ expect(new Code().renderWrapper).toBe("<code ></code>")
8
8
  })
9
9
 
10
10
  it("returns attributes and data attributes", () => {
11
- expect(new Code({ id: "1", "data-foo": "bar" }).render).toBe(`<code id='1' data-foo='bar'></code>`)
11
+ expect(new Code({ id: "1", "data-foo": "bar" }).renderWrapper).toBe(`<code id='1' data-foo='bar'></code>`)
12
12
  })
13
13
 
14
14
  it("returns attributes and data attributes with custom data attributes", () => {
15
- expect(new Code({ id: "1", data: { foo: "bar" } }).render).toBe(`<code id='1' data-foo='bar'></code>`)
16
- expect(new Code({ id: "1", data: { foo: "bar", baz: "qux" } }).render).toBe(`<code id='1' data-foo='bar' data-baz='qux'></code>`)
17
- expect(new Code({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).render).toBe(`<code id='1' data-foo-baz='qux' data-foo-quux='corge'></code>`)
15
+ expect(new Code({ id: "1", data: { foo: "bar" } }).renderWrapper).toBe(`<code id='1' data-foo='bar'></code>`)
16
+ expect(new Code({ id: "1", data: { foo: "bar", baz: "qux" } }).renderWrapper).toBe(`<code id='1' data-foo='bar' data-baz='qux'></code>`)
17
+ expect(new Code({ id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toBe(`<code id='1' data-foo-baz='qux' data-foo-quux='corge'></code>`)
18
18
  })
19
19
 
20
20
  it("adds children", () => {
21
21
  const text = new Text("Hello")
22
22
  const code = new Code()
23
23
  code.add(text)
24
- expect(code.render).toBe(`<code >Hello</code>`)
24
+ expect(code.renderWrapper).toBe(`<code >Hello</code>`)
25
25
  })
26
26
  })
@@ -9,8 +9,8 @@ export class Code {
9
9
  this.attributes = attributes;
10
10
  }
11
11
 
12
- get render(): string {
13
- return `<code ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</code>`;
12
+ get renderWrapper(): string {
13
+ return `<code ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</code>`;
14
14
  }
15
15
 
16
16
  add(child: any): Code {
@@ -5,18 +5,22 @@ export class Component {
5
5
  id: string;
6
6
  _state: any;
7
7
  _errors: any[];
8
- _root: Box;
9
8
  _c: Presets;
10
9
 
11
10
  constructor(state: any = {}, id: string = Math.random().toString(36).substring(2, 10), errors: any[] = []) {
12
11
  this._state = state;
13
12
  this.id = id;
14
13
  this._errors = errors;
15
- this._root = new Box({ data: { component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } });
16
14
  this._c = new Presets()
17
15
  }
18
16
 
19
- get render(): string {
20
- return this._root.render;
17
+ get render(): any {
18
+ return new Box({});
19
+ }
20
+
21
+ get renderWrapper(): string {
22
+ const root = this.render;
23
+ root.attributes = { ...root.attributes, data: { ...root.attributes.data, component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } };
24
+ return root.renderWrapper;
21
25
  }
22
26
  }
@@ -3,14 +3,14 @@ import { DateTimeField } from "./datetime-field"
3
3
 
4
4
  describe("DateTimeField", () => {
5
5
  it("returns empty string if no params", () => {
6
- expect(new DateTimeField({}, "foo").render).toBe("<input type='datetime-local' data-attribute='foo' value=''/>")
6
+ expect(new DateTimeField({}, "foo").renderWrapper).toBe("<input type='datetime-local' data-attribute='foo' value=''/>")
7
7
  })
8
8
 
9
9
  it("returns attributes and data attributes", () => {
10
- expect(new DateTimeField({ foo: new Date("2024-10-12T12:00") }, "foo", { id: "1", "data-foo": "bar" }).render).toMatch(/<input type='datetime-local' id='1' data-foo='bar' data-attribute='foo' value='.+'\/>/)
10
+ expect(new DateTimeField({ foo: new Date("2024-10-12T12:00") }, "foo", { id: "1", "data-foo": "bar" }).renderWrapper).toMatch(/<input type='datetime-local' id='1' data-foo='bar' data-attribute='foo' value='.+'\/>/)
11
11
  })
12
12
 
13
13
  it("returns attributes and data attributes with custom data attributes", () => {
14
- expect(new DateTimeField({ foo: new Date("2024-10-12T12:00") }, "foo", { id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).render).toMatch(/<input type='datetime-local' id='1' data-attribute='foo' data-foo-baz='qux' data-foo-quux='corge' value='.+'\/>/)
14
+ expect(new DateTimeField({ foo: new Date("2024-10-12T12:00") }, "foo", { id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toMatch(/<input type='datetime-local' id='1' data-attribute='foo' data-foo-baz='qux' data-foo-quux='corge' value='.+'\/>/)
15
15
  })
16
16
  })
@@ -12,7 +12,7 @@ export class DateTimeField {
12
12
  this.attributes["data-attribute"] = attribute;
13
13
  }
14
14
 
15
- get render(): string {
15
+ get renderWrapper(): string {
16
16
  const value = this.state[this.attribute] ? this.datetime_local_value(this.state[this.attribute]) : "";
17
17
  return `<input type='datetime-local' ${htmlAttributes(this.attributes)} value='${value}'/>`;
18
18
  }
@@ -5,23 +5,23 @@ import { Text } from "./text"
5
5
 
6
6
  describe("Element", () => {
7
7
  it("returns empty string if no params", () => {
8
- expect(new Element("blockquote").render).toBe("<blockquote ></blockquote>")
8
+ expect(new Element("blockquote").renderWrapper).toBe("<blockquote ></blockquote>")
9
9
  })
10
10
 
11
11
  it("returns attributes and data attributes", () => {
12
- expect(new Element("blockquote", { id: "1", "data-foo": "bar" }).render).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
12
+ expect(new Element("blockquote", { id: "1", "data-foo": "bar" }).renderWrapper).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
13
13
  })
14
14
 
15
15
  it("returns attributes and data attributes with custom data attributes", () => {
16
- expect(new Element("blockquote", { id: "1", data: { foo: "bar" } }).render).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
17
- expect(new Element("blockquote", { id: "1", data: { foo: "bar", baz: "qux" } }).render).toBe(`<blockquote id='1' data-foo='bar' data-baz='qux'></blockquote>`)
18
- expect(new Element("blockquote", { id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).render).toBe(`<blockquote id='1' data-foo-baz='qux' data-foo-quux='corge'></blockquote>`)
16
+ expect(new Element("blockquote", { id: "1", data: { foo: "bar" } }).renderWrapper).toBe(`<blockquote id='1' data-foo='bar'></blockquote>`)
17
+ expect(new Element("blockquote", { id: "1", data: { foo: "bar", baz: "qux" } }).renderWrapper).toBe(`<blockquote id='1' data-foo='bar' data-baz='qux'></blockquote>`)
18
+ expect(new Element("blockquote", { id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toBe(`<blockquote id='1' data-foo-baz='qux' data-foo-quux='corge'></blockquote>`)
19
19
  })
20
20
 
21
21
  it("adds children", () => {
22
22
  const text = new Text("Hello")
23
23
  const blockQuote = new Element("blockquote")
24
24
  blockQuote.add(text)
25
- expect(blockQuote.render).toBe(`<blockquote >Hello</blockquote>`)
25
+ expect(blockQuote.renderWrapper).toBe(`<blockquote >Hello</blockquote>`)
26
26
  })
27
27
  })