clapton 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ced6ec2a5091225623d714847395bbbe1a5aa58d8b655b8fd9ba427a3cad253a
4
- data.tar.gz: 15d4b56faaa648195800818fae39753ebbf66b18551042397217f9913ffbdb7a
3
+ metadata.gz: 01e0976bdfdb23e447884dec93ee2f25ceb2d5e0312ca4a54aeed3ba603a69c2
4
+ data.tar.gz: e950680f7a0928e186eb14ae04d1479e741e55670ec16ee97a6cc4b799edeb0e
5
5
  SHA512:
6
- metadata.gz: 94e5dd398e4264ef1a8a4429fb34dbb9bfc80abf3e162712cf6fea236f0991209bbfc04e19a550590e0af739ccef393e1325bc19a0c1daa04b697d12b77436cd
7
- data.tar.gz: faea93854fc326fa2933df5a191cc079296c751153a88cd5d93432db8cb4d0671d5c8a18a0b13534437f760996dfe1a2200162e3c3ce618389ef7a8c28075992
6
+ metadata.gz: d3ed3bd257263eb9875acb301c798d18bed14700cbed7352b8ac55187e320f8a49a555a6fbbd90e3db6980c9b4572ed62371a7d3f16af7b60a858a1ab02102de
7
+ data.tar.gz: d89a048e4c2df53e1fb35c01063c6f59e3eef7f3737907b8523c8c919ad2eb84fc7cce63f138455ecf6d29650df12a387d64e7e348fedfffdc47760cf6b14393
data/README.md CHANGED
@@ -137,6 +137,12 @@ mount Clapton::Engine => "/clapton"
137
137
 
138
138
  ![TODO APP DEMO](./docs/todo-app-demo.gif)
139
139
 
140
+ ### Component rendering
141
+
142
+ ```html
143
+ <%= clapton_component_tag([:TaskListComponent, { tasks: @tasks.map { |task| { id: task.id, title: task.title, due: task.due, done: task.done } }]) %>
144
+ ```
145
+
140
146
  ### Generate Component and State
141
147
 
142
148
  ```bash
@@ -17,5 +17,15 @@ module Clapton
17
17
  end
18
18
  tag.div(id: "clapton", data: { clapton: datas })
19
19
  end
20
+
21
+ def clapton_component_tag(component)
22
+ state_class = component[0].to_s.gsub("Component", "State")
23
+ if Object.const_defined?(state_class)
24
+ data = { component: component[0].to_s, state: Object.const_get(state_class).new(component[1]).to_h }
25
+ else
26
+ data = { component: component[0].to_s, state: {} }
27
+ end
28
+ tag.div(class: "clapton-component", data: { clapton: data })
29
+ end
20
30
  end
21
31
  end
@@ -1393,15 +1393,19 @@ const initializeInputs$1 = () => {
1393
1393
 
1394
1394
  const initializeComponents = () => {
1395
1395
  const components = document.querySelector("#clapton")?.getAttribute("data-clapton") || "[]";
1396
- JSON.parse(components).forEach(createAndAppendComponent);
1396
+ JSON.parse(components).forEach((component) => createAndAppendComponent(component, document.querySelector("#clapton")));
1397
+ document.querySelectorAll(".clapton-component").forEach((element) => {
1398
+ const component = JSON.parse(element.getAttribute("data-clapton") || "{}");
1399
+ createAndAppendComponent(component, element);
1400
+ });
1397
1401
  };
1398
- const createAndAppendComponent = (component) => {
1402
+ const createAndAppendComponent = (component, element) => {
1399
1403
  const componentDom = document.createElement('div');
1400
1404
  const instance = new window[component.component](component.state);
1401
1405
  componentDom.innerHTML = instance.render;
1402
1406
  const firstChild = componentDom.firstChild;
1403
1407
  if (firstChild) {
1404
- document.querySelector("#clapton")?.appendChild(firstChild);
1408
+ element.appendChild(firstChild);
1405
1409
  }
1406
1410
  };
1407
1411
  document.addEventListener("DOMContentLoaded", () => {
@@ -43,42 +43,53 @@ var Clapton = (function (exports) {
43
43
  .replace(/'/g, "&#039;");
44
44
  };
45
45
 
46
- class Box {
46
+ class BlockQuote {
47
47
  constructor(attributes = {}) {
48
48
  this.children = [];
49
49
  this.attributes = attributes;
50
50
  }
51
+ get render() {
52
+ return `<blockquote ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</blockquote>`;
53
+ }
51
54
  add(child) {
52
55
  this.children.push(child);
53
56
  return this;
54
57
  }
55
- get render() {
56
- return `<div ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</div>`;
57
- }
58
58
  }
59
59
 
60
- class Component {
61
- constructor(state = {}, id = Math.random().toString(36).substring(2, 10), errors = []) {
62
- this._state = state;
63
- this.id = id;
64
- this._errors = errors;
65
- this._root = new Box({ data: { component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } });
60
+ class Box {
61
+ constructor(attributes = {}) {
62
+ this.children = [];
63
+ this.attributes = attributes;
64
+ }
65
+ add(child) {
66
+ this.children.push(child);
67
+ return this;
66
68
  }
67
69
  get render() {
68
- return this._root.render;
70
+ return `<div ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</div>`;
69
71
  }
70
72
  }
71
73
 
72
- class Text {
73
- constructor(value) {
74
- this.value = value;
74
+ class Button {
75
+ constructor(attributes = {}) {
76
+ this.attributes = attributes;
77
+ this.children = [];
78
+ }
79
+ add(child) {
80
+ this.children.push(child);
81
+ return this;
75
82
  }
76
83
  get render() {
77
- return this.value;
84
+ return `<button ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</button>`;
85
+ }
86
+ add_action(event, klass, fn, options = {}) {
87
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
88
+ return this;
78
89
  }
79
90
  }
80
91
 
81
- class TextField {
92
+ class Checkbox {
82
93
  constructor(state, attribute, attributes = {}) {
83
94
  this.state = state;
84
95
  this.attributes = attributes;
@@ -86,7 +97,7 @@ var Clapton = (function (exports) {
86
97
  this.attributes["data-attribute"] = attribute;
87
98
  }
88
99
  get render() {
89
- return `<input type='text' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
100
+ return `<input type='checkbox' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
90
101
  }
91
102
  add_action(event, klass, fn, options = {}) {
92
103
  this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
@@ -94,36 +105,18 @@ var Clapton = (function (exports) {
94
105
  }
95
106
  }
96
107
 
97
- class Link {
108
+ class Code {
98
109
  constructor(attributes = {}) {
99
110
  this.children = [];
100
111
  this.attributes = attributes;
101
112
  }
102
113
  get render() {
103
- return `<a ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</a>`;
104
- }
105
- add(child) {
106
- this.children.push(child);
107
- return this;
108
- }
109
- }
110
-
111
- class Button {
112
- constructor(attributes = {}) {
113
- this.attributes = attributes;
114
- this.children = [];
114
+ return `<code ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</code>`;
115
115
  }
116
116
  add(child) {
117
117
  this.children.push(child);
118
118
  return this;
119
119
  }
120
- get render() {
121
- return `<button ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</button>`;
122
- }
123
- add_action(event, klass, fn, options = {}) {
124
- this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
125
- return this;
126
- }
127
120
  }
128
121
 
129
122
  class DateTimeField {
@@ -168,11 +161,262 @@ var Clapton = (function (exports) {
168
161
  }
169
162
  }
170
163
 
164
+ class Element {
165
+ constructor(type, attributes = {}) {
166
+ this.children = [];
167
+ this.type = type;
168
+ this.attributes = attributes;
169
+ }
170
+ get render() {
171
+ return `<${this.type} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</${this.type}>`;
172
+ }
173
+ add(child) {
174
+ this.children.push(child);
175
+ return this;
176
+ }
177
+ }
178
+
179
+ class Emphasis {
180
+ constructor(attributes = {}) {
181
+ this.children = [];
182
+ this.attributes = attributes;
183
+ }
184
+ get render() {
185
+ return `<em ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</em>`;
186
+ }
187
+ add(child) {
188
+ this.children.push(child);
189
+ return this;
190
+ }
191
+ }
192
+
193
+ class Form {
194
+ constructor(attributes = {}) {
195
+ this.children = [];
196
+ this.attributes = attributes;
197
+ }
198
+ get render() {
199
+ return `<form ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</form>`;
200
+ }
201
+ add(child) {
202
+ this.children.push(child);
203
+ return this;
204
+ }
205
+ }
206
+
207
+ class Heading {
208
+ constructor(level, attributes = {}) {
209
+ this.children = [];
210
+ this.level = level;
211
+ this.attributes = attributes;
212
+ }
213
+ get render() {
214
+ return `<h${this.level} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</h${this.level}>`;
215
+ }
216
+ add(child) {
217
+ this.children.push(child);
218
+ return this;
219
+ }
220
+ }
221
+
222
+ class Image {
223
+ constructor(src, alt, attributes = {}) {
224
+ this.children = [];
225
+ this.attributes = attributes;
226
+ this.src = src;
227
+ this.alt = alt;
228
+ }
229
+ get render() {
230
+ return `<img src='${this.src}' alt='${this.alt}' ${htmlAttributes(this.attributes)}/>`;
231
+ }
232
+ }
233
+
234
+ class Link {
235
+ constructor(href, attributes = {}) {
236
+ this.children = [];
237
+ this.attributes = attributes;
238
+ this.href = href;
239
+ }
240
+ get render() {
241
+ return `<a href='${this.href}' ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</a>`;
242
+ }
243
+ add(child) {
244
+ this.children.push(child);
245
+ return this;
246
+ }
247
+ }
248
+
249
+ class ListItem {
250
+ constructor(attributes = {}) {
251
+ this.children = [];
252
+ this.attributes = attributes;
253
+ }
254
+ add(child) {
255
+ this.children.push(child);
256
+ return this;
257
+ }
258
+ get render() {
259
+ return `<li ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</li>`;
260
+ }
261
+ }
262
+
263
+ class List {
264
+ constructor(attributes = {}) {
265
+ this.children = [];
266
+ this.attributes = attributes;
267
+ }
268
+ add(child) {
269
+ this.children.push(child);
270
+ return this;
271
+ }
272
+ get render() {
273
+ return `<ul ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</ul>`;
274
+ }
275
+ }
276
+
277
+ class OrderedList {
278
+ constructor(attributes = {}) {
279
+ this.children = [];
280
+ this.attributes = attributes;
281
+ }
282
+ add(child) {
283
+ this.children.push(child);
284
+ return this;
285
+ }
286
+ get render() {
287
+ return `<ol ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</ol>`;
288
+ }
289
+ }
290
+
291
+ class Paragraph {
292
+ constructor(attributes = {}) {
293
+ this.children = [];
294
+ this.attributes = attributes;
295
+ }
296
+ get render() {
297
+ return `<p ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</p>`;
298
+ }
299
+ add(child) {
300
+ this.children.push(child);
301
+ return this;
302
+ }
303
+ }
304
+
305
+ class Quote {
306
+ constructor(attributes = {}) {
307
+ this.children = [];
308
+ this.attributes = attributes;
309
+ }
310
+ get render() {
311
+ return `<q ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</q>`;
312
+ }
313
+ add(child) {
314
+ this.children.push(child);
315
+ return this;
316
+ }
317
+ }
318
+
319
+ class RadioButton {
320
+ constructor(state, attribute, attributes = {}) {
321
+ this.state = state;
322
+ this.attributes = attributes;
323
+ this.attribute = attribute;
324
+ this.attributes["data-attribute"] = attribute;
325
+ }
326
+ get render() {
327
+ return `<input type='radio' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
328
+ }
329
+ add_action(event, klass, fn, options = {}) {
330
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
331
+ return this;
332
+ }
333
+ }
334
+
335
+ class Select {
336
+ constructor(options = [], state, attribute, attributes = {}) {
337
+ this.children = [];
338
+ this.options = options;
339
+ this.state = state;
340
+ this.attribute = attribute;
341
+ this.attributes = attributes;
342
+ }
343
+ get render() {
344
+ 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>`;
345
+ }
346
+ }
347
+
348
+ class Span {
349
+ constructor(attributes = {}) {
350
+ this.children = [];
351
+ this.attributes = attributes;
352
+ }
353
+ get render() {
354
+ return `<span ${htmlAttributes(this.attributes)}>${this.children.map(child => child.render).join("")}</span>`;
355
+ }
356
+ add(child) {
357
+ this.children.push(child);
358
+ return this;
359
+ }
360
+ }
361
+
362
+ class Component {
363
+ constructor(state = {}, id = Math.random().toString(36).substring(2, 10), errors = []) {
364
+ this._state = state;
365
+ this.id = id;
366
+ this._errors = errors;
367
+ this._root = new Box({ data: { component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } });
368
+ }
369
+ get render() {
370
+ return this._root.render;
371
+ }
372
+ }
373
+
374
+ class TextField {
375
+ constructor(state, attribute, attributes = {}) {
376
+ this.state = state;
377
+ this.attributes = attributes;
378
+ this.attribute = attribute;
379
+ this.attributes["data-attribute"] = attribute;
380
+ }
381
+ get render() {
382
+ return `<input type='text' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
383
+ }
384
+ add_action(event, klass, fn, options = {}) {
385
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
386
+ return this;
387
+ }
388
+ }
389
+
390
+ class Text {
391
+ constructor(value) {
392
+ this.value = value;
393
+ }
394
+ get render() {
395
+ return this.value;
396
+ }
397
+ }
398
+
399
+ exports.BlockQuote = BlockQuote;
171
400
  exports.Box = Box;
172
401
  exports.Button = Button;
402
+ exports.Checkbox = Checkbox;
403
+ exports.Code = Code;
173
404
  exports.Component = Component;
174
405
  exports.DateTimeField = DateTimeField;
406
+ exports.Element = Element;
407
+ exports.Emphasis = Emphasis;
408
+ exports.Form = Form;
409
+ exports.Heading = Heading;
410
+ exports.Image = Image;
175
411
  exports.Link = Link;
412
+ exports.List = List;
413
+ exports.ListItem = ListItem;
414
+ exports.OrderedList = OrderedList;
415
+ exports.Paragraph = Paragraph;
416
+ exports.Quote = Quote;
417
+ exports.RadioButton = RadioButton;
418
+ exports.Select = Select;
419
+ exports.Span = Span;
176
420
  exports.Text = Text;
177
421
  exports.TextField = TextField;
178
422
 
@@ -17,16 +17,20 @@ interface ComponentInstance {
17
17
 
18
18
  const initializeComponents = () => {
19
19
  const components = document.querySelector("#clapton")?.getAttribute("data-clapton") || "[]";
20
- JSON.parse(components).forEach(createAndAppendComponent);
20
+ JSON.parse(components).forEach((component: ComponentDefinition) => createAndAppendComponent(component, document.querySelector("#clapton")!));
21
+ document.querySelectorAll(".clapton-component").forEach((element) => {
22
+ const component = JSON.parse(element.getAttribute("data-clapton") || "{}");
23
+ createAndAppendComponent(component, element as HTMLElement);
24
+ });
21
25
  };
22
26
 
23
- const createAndAppendComponent = (component: ComponentDefinition) => {
27
+ const createAndAppendComponent = (component: ComponentDefinition, element: HTMLElement) => {
24
28
  const componentDom = document.createElement('div');
25
29
  const instance = new (window[component.component as any] as any)(component.state);
26
30
  componentDom.innerHTML = instance.render;
27
31
  const firstChild = componentDom.firstChild as HTMLElement;
28
32
  if (firstChild) {
29
- document.querySelector("#clapton")?.appendChild(firstChild);
33
+ element.appendChild(firstChild);
30
34
  }
31
35
  };
32
36
 
@@ -1,3 +1,3 @@
1
1
  module Clapton
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.7'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clapton
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moeki Kawakami