clapton 0.0.25 → 0.0.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/channels/clapton/clapton_channel.rb +4 -0
- data/lib/clapton/javascripts/dist/c-for-test.js +19 -0
- data/lib/clapton/javascripts/dist/c.js +19 -0
- data/lib/clapton/javascripts/dist/client.js +6 -31
- data/lib/clapton/javascripts/dist/components-for-test.js +4 -0
- data/lib/clapton/javascripts/dist/components.js +4 -0
- data/lib/clapton/javascripts/src/actions/handle-action.ts +3 -2
- data/lib/clapton/javascripts/src/c-base.ts +15 -0
- data/lib/clapton/javascripts/src/channel/clapton-channel.js +3 -2
- data/lib/clapton/javascripts/src/client.ts +0 -3
- data/lib/clapton/javascripts/src/components/input.spec.ts +3 -3
- data/lib/clapton/javascripts/src/components/input.ts +4 -0
- data/lib/clapton/version.rb +1 -1
- metadata +1 -3
- data/lib/clapton/javascripts/src/dom/update-component.ts +0 -11
- data/lib/clapton/javascripts/src/inputs/initialize-inputs.ts +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7e101f28b9097e8229c855012c0c2649da46060207845c7d6f41c6a1e6c89b3
|
4
|
+
data.tar.gz: e1d8c859a3e5e675922a6a79a9783b0129c33fa2f30f56cf2819dac7802e85ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f0a863288caa1f2ff959a14ae745c6043aaece8642ece8428ac91695a036f1601088bc81dc562c9bc3bf140101e8b210f47990b77ba26dbf2b07597225ec1c9
|
7
|
+
data.tar.gz: 75d7c625ce602ff727709bfe217e79e19f6c17a11ddceecbb4d8c5765ea353206a4763f4e182ffcb7081842d9485d13b21127d39536ae3270967d5362467cd0f
|
@@ -19,6 +19,7 @@ module Clapton
|
|
19
19
|
id: data["data"]["component"]["id"],
|
20
20
|
},
|
21
21
|
state: state.to_h,
|
22
|
+
focus: data["data"]["focus"]
|
22
23
|
}
|
23
24
|
})
|
24
25
|
end
|
@@ -32,6 +33,7 @@ module Clapton
|
|
32
33
|
id: data["data"]["component"]["id"],
|
33
34
|
},
|
34
35
|
state: state.to_h,
|
36
|
+
focus: data["data"]["focus"]
|
35
37
|
}
|
36
38
|
})
|
37
39
|
return
|
@@ -47,6 +49,7 @@ module Clapton
|
|
47
49
|
id: data["data"]["component"]["id"],
|
48
50
|
},
|
49
51
|
state: state.to_h,
|
52
|
+
focus: data["data"]["focus"]
|
50
53
|
}
|
51
54
|
})
|
52
55
|
else
|
@@ -59,6 +62,7 @@ module Clapton
|
|
59
62
|
id: data["data"]["component"]["id"],
|
60
63
|
},
|
61
64
|
state: state.to_h,
|
65
|
+
focus: data["data"]["focus"]
|
62
66
|
}
|
63
67
|
})
|
64
68
|
end
|
@@ -241,9 +241,13 @@ var c = (function () {
|
|
241
241
|
this.attribute = attribute;
|
242
242
|
this.state = state;
|
243
243
|
this.attributes["data-attribute"] = attribute;
|
244
|
+
this.attributes["data-id"] = Math.random().toString(36).substring(2, 10);
|
244
245
|
}
|
245
246
|
get renderWrapper() {
|
246
247
|
let value = this.state[this.attribute];
|
248
|
+
if (!this.attributes.type) {
|
249
|
+
this.attributes.type = "text";
|
250
|
+
}
|
247
251
|
if (this.attributes.type === "datetime-local" && value) {
|
248
252
|
value = this.datetime_local_value(value);
|
249
253
|
}
|
@@ -383,6 +387,10 @@ var c = (function () {
|
|
383
387
|
};
|
384
388
|
const c = (name, ...props) => {
|
385
389
|
switch (name) {
|
390
|
+
case "bq":
|
391
|
+
return blockquote(...props);
|
392
|
+
case "box":
|
393
|
+
return div(...props);
|
386
394
|
case "blockquote":
|
387
395
|
return blockquote(...props);
|
388
396
|
case "div":
|
@@ -401,6 +409,8 @@ var c = (function () {
|
|
401
409
|
return em(...props);
|
402
410
|
case "form":
|
403
411
|
return form(...props);
|
412
|
+
case "h":
|
413
|
+
return h1(...props);
|
404
414
|
case "h1":
|
405
415
|
return h1(...props);
|
406
416
|
case "h2":
|
@@ -437,6 +447,15 @@ var c = (function () {
|
|
437
447
|
return input(...props);
|
438
448
|
case "text":
|
439
449
|
return text(...props);
|
450
|
+
case "radio":
|
451
|
+
props[3].type = "radio";
|
452
|
+
return input(...props);
|
453
|
+
case "datetime":
|
454
|
+
props[3].type = "datetime-local";
|
455
|
+
return input(...props);
|
456
|
+
case "check":
|
457
|
+
props[3].type = "checkbox";
|
458
|
+
return input(...props);
|
440
459
|
default:
|
441
460
|
return new Clapton.Element(name, ...props);
|
442
461
|
}
|
@@ -238,9 +238,13 @@ class Input extends Base {
|
|
238
238
|
this.attribute = attribute;
|
239
239
|
this.state = state;
|
240
240
|
this.attributes["data-attribute"] = attribute;
|
241
|
+
this.attributes["data-id"] = Math.random().toString(36).substring(2, 10);
|
241
242
|
}
|
242
243
|
get renderWrapper() {
|
243
244
|
let value = this.state[this.attribute];
|
245
|
+
if (!this.attributes.type) {
|
246
|
+
this.attributes.type = "text";
|
247
|
+
}
|
244
248
|
if (this.attributes.type === "datetime-local" && value) {
|
245
249
|
value = this.datetime_local_value(value);
|
246
250
|
}
|
@@ -380,6 +384,10 @@ const text = (...props) => {
|
|
380
384
|
};
|
381
385
|
const c = (name, ...props) => {
|
382
386
|
switch (name) {
|
387
|
+
case "bq":
|
388
|
+
return blockquote(...props);
|
389
|
+
case "box":
|
390
|
+
return div(...props);
|
383
391
|
case "blockquote":
|
384
392
|
return blockquote(...props);
|
385
393
|
case "div":
|
@@ -398,6 +406,8 @@ const c = (name, ...props) => {
|
|
398
406
|
return em(...props);
|
399
407
|
case "form":
|
400
408
|
return form(...props);
|
409
|
+
case "h":
|
410
|
+
return h1(...props);
|
401
411
|
case "h1":
|
402
412
|
return h1(...props);
|
403
413
|
case "h2":
|
@@ -434,6 +444,15 @@ const c = (name, ...props) => {
|
|
434
444
|
return input(...props);
|
435
445
|
case "text":
|
436
446
|
return text(...props);
|
447
|
+
case "radio":
|
448
|
+
props[3].type = "radio";
|
449
|
+
return input(...props);
|
450
|
+
case "datetime":
|
451
|
+
props[3].type = "datetime-local";
|
452
|
+
return input(...props);
|
453
|
+
case "check":
|
454
|
+
props[3].type = "checkbox";
|
455
|
+
return input(...props);
|
437
456
|
default:
|
438
457
|
return new Clapton.Element(name, ...props);
|
439
458
|
}
|
@@ -1285,32 +1285,6 @@ function getConfig(name) {
|
|
1285
1285
|
}
|
1286
1286
|
}
|
1287
1287
|
|
1288
|
-
const updateComponent = async (component, state, property, target) => {
|
1289
|
-
state[property] = target.value;
|
1290
|
-
const componentName = component.dataset.component;
|
1291
|
-
const module = await import(`${componentName}`);
|
1292
|
-
const ComponentClass = module[componentName];
|
1293
|
-
const instance = new ComponentClass(state, component.dataset.id);
|
1294
|
-
morphdom(component, instance.renderWrapper);
|
1295
|
-
instance.runEffects();
|
1296
|
-
};
|
1297
|
-
|
1298
|
-
const initializeInputs = () => {
|
1299
|
-
const inputElements = document.querySelectorAll("[data-attribute]");
|
1300
|
-
inputElements.forEach((element) => {
|
1301
|
-
const attribute = element.getAttribute("data-attribute");
|
1302
|
-
const component = element.closest(`[data-component]`);
|
1303
|
-
const state = JSON.parse(component.getAttribute("data-state") || "{}");
|
1304
|
-
if (!attribute || !component)
|
1305
|
-
return;
|
1306
|
-
if (element.tagName === "INPUT") {
|
1307
|
-
element.addEventListener("input", async (event) => {
|
1308
|
-
await updateComponent(component, state, attribute, event.target);
|
1309
|
-
});
|
1310
|
-
}
|
1311
|
-
});
|
1312
|
-
};
|
1313
|
-
|
1314
1288
|
const consumer = createConsumer();
|
1315
1289
|
|
1316
1290
|
const claptonChannel = consumer.subscriptions.create("Clapton::ClaptonChannel", {
|
@@ -1327,12 +1301,14 @@ const claptonChannel = consumer.subscriptions.create("Clapton::ClaptonChannel",
|
|
1327
1301
|
const instance = new module[data.component.name](data.state, data.component.id, errors);
|
1328
1302
|
morphdom(component, instance.renderWrapper, {
|
1329
1303
|
onBeforeElUpdated: (_fromEl, toEl) => {
|
1304
|
+
if (_fromEl.dataset.id === data.focus) {
|
1305
|
+
return false;
|
1306
|
+
}
|
1330
1307
|
toEl.setAttribute("data-set-event-handler", "true");
|
1331
1308
|
return true;
|
1332
1309
|
}
|
1333
1310
|
});
|
1334
1311
|
|
1335
|
-
initializeInputs();
|
1336
1312
|
initializeActions();
|
1337
1313
|
instance.runEffects();
|
1338
1314
|
}
|
@@ -1352,7 +1328,7 @@ const handleAction = async (target, stateName, fn) => {
|
|
1352
1328
|
const attribute = target.dataset.attribute;
|
1353
1329
|
if (attribute) {
|
1354
1330
|
const state = JSON.parse(component.dataset.state || "{}");
|
1355
|
-
if (target.
|
1331
|
+
if (target.dataset.attribute) {
|
1356
1332
|
state[attribute] = target.value;
|
1357
1333
|
component.dataset.state = JSON.stringify(state);
|
1358
1334
|
}
|
@@ -1368,7 +1344,8 @@ const handleAction = async (target, stateName, fn) => {
|
|
1368
1344
|
action: fn,
|
1369
1345
|
attributes: JSON.parse(targetComponent.dataset.state || "{}"),
|
1370
1346
|
},
|
1371
|
-
params: JSON.parse(component.dataset.state || "{}")
|
1347
|
+
params: JSON.parse(component.dataset.state || "{}"),
|
1348
|
+
focus: target.dataset.id,
|
1372
1349
|
}
|
1373
1350
|
});
|
1374
1351
|
};
|
@@ -1447,14 +1424,12 @@ const createAndAppendComponent = async (component, element) => {
|
|
1447
1424
|
document.addEventListener("DOMContentLoaded", async () => {
|
1448
1425
|
await initializeComponents();
|
1449
1426
|
initializeActions();
|
1450
|
-
initializeInputs();
|
1451
1427
|
const event = new Event('clapton:render');
|
1452
1428
|
document.dispatchEvent(event);
|
1453
1429
|
});
|
1454
1430
|
document.addEventListener("turbo:render", async () => {
|
1455
1431
|
await initializeComponents();
|
1456
1432
|
initializeActions();
|
1457
|
-
initializeInputs();
|
1458
1433
|
const event = new Event('clapton:render');
|
1459
1434
|
document.dispatchEvent(event);
|
1460
1435
|
});
|
@@ -241,9 +241,13 @@ var Clapton = (function (exports) {
|
|
241
241
|
this.attribute = attribute;
|
242
242
|
this.state = state;
|
243
243
|
this.attributes["data-attribute"] = attribute;
|
244
|
+
this.attributes["data-id"] = Math.random().toString(36).substring(2, 10);
|
244
245
|
}
|
245
246
|
get renderWrapper() {
|
246
247
|
let value = this.state[this.attribute];
|
248
|
+
if (!this.attributes.type) {
|
249
|
+
this.attributes.type = "text";
|
250
|
+
}
|
247
251
|
if (this.attributes.type === "datetime-local" && value) {
|
248
252
|
value = this.datetime_local_value(value);
|
249
253
|
}
|
@@ -238,9 +238,13 @@ class Input extends Base {
|
|
238
238
|
this.attribute = attribute;
|
239
239
|
this.state = state;
|
240
240
|
this.attributes["data-attribute"] = attribute;
|
241
|
+
this.attributes["data-id"] = Math.random().toString(36).substring(2, 10);
|
241
242
|
}
|
242
243
|
get renderWrapper() {
|
243
244
|
let value = this.state[this.attribute];
|
245
|
+
if (!this.attributes.type) {
|
246
|
+
this.attributes.type = "text";
|
247
|
+
}
|
244
248
|
if (this.attributes.type === "datetime-local" && value) {
|
245
249
|
value = this.datetime_local_value(value);
|
246
250
|
}
|
@@ -12,7 +12,7 @@ export const handleAction = async (target: HTMLElement, stateName: string, fn: s
|
|
12
12
|
const attribute = target.dataset.attribute;
|
13
13
|
if (attribute) {
|
14
14
|
const state = JSON.parse(component.dataset.state || "{}");
|
15
|
-
if (target.
|
15
|
+
if (target.dataset.attribute) {
|
16
16
|
state[attribute] = (target as HTMLInputElement).value;
|
17
17
|
component.dataset.state = JSON.stringify(state);
|
18
18
|
}
|
@@ -30,7 +30,8 @@ export const handleAction = async (target: HTMLElement, stateName: string, fn: s
|
|
30
30
|
action: fn,
|
31
31
|
attributes: JSON.parse(targetComponent.dataset.state || "{}"),
|
32
32
|
},
|
33
|
-
params: JSON.parse(component.dataset.state || "{}")
|
33
|
+
params: JSON.parse(component.dataset.state || "{}"),
|
34
|
+
focus: target.dataset.id,
|
34
35
|
}
|
35
36
|
}
|
36
37
|
);
|
@@ -110,6 +110,10 @@ const text = (...props: any[]) => {
|
|
110
110
|
|
111
111
|
const c = (name: string, ...props: any[]) => {
|
112
112
|
switch (name) {
|
113
|
+
case "bq":
|
114
|
+
return blockquote(...props)
|
115
|
+
case "box":
|
116
|
+
return div(...props)
|
113
117
|
case "blockquote":
|
114
118
|
return blockquote(...props)
|
115
119
|
case "div":
|
@@ -128,6 +132,8 @@ const c = (name: string, ...props: any[]) => {
|
|
128
132
|
return em(...props)
|
129
133
|
case "form":
|
130
134
|
return form(...props)
|
135
|
+
case "h":
|
136
|
+
return h1(...props)
|
131
137
|
case "h1":
|
132
138
|
return h1(...props)
|
133
139
|
case "h2":
|
@@ -164,6 +170,15 @@ const c = (name: string, ...props: any[]) => {
|
|
164
170
|
return input(...props)
|
165
171
|
case "text":
|
166
172
|
return text(...props)
|
173
|
+
case "radio":
|
174
|
+
props[3].type = "radio"
|
175
|
+
return input(...props)
|
176
|
+
case "datetime":
|
177
|
+
props[3].type = "datetime-local"
|
178
|
+
return input(...props)
|
179
|
+
case "check":
|
180
|
+
props[3].type = "checkbox"
|
181
|
+
return input(...props)
|
167
182
|
default:
|
168
183
|
return new Clapton.Element(name, ...props)
|
169
184
|
}
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import morphdom from "morphdom"
|
2
2
|
import { createConsumer } from "@rails/actioncable"
|
3
3
|
import { initializeActions } from "../actions/initialize-actions.ts"
|
4
|
-
import { initializeInputs } from "../inputs/initialize-inputs.ts"
|
5
4
|
const consumer = createConsumer()
|
6
5
|
|
7
6
|
export const claptonChannel = consumer.subscriptions.create("Clapton::ClaptonChannel", {
|
@@ -18,12 +17,14 @@ export const claptonChannel = consumer.subscriptions.create("Clapton::ClaptonCha
|
|
18
17
|
const instance = new module[data.component.name](data.state, data.component.id, errors);
|
19
18
|
morphdom(component, instance.renderWrapper, {
|
20
19
|
onBeforeElUpdated: (_fromEl, toEl) => {
|
20
|
+
if (_fromEl.dataset.id === data.focus) {
|
21
|
+
return false;
|
22
|
+
}
|
21
23
|
toEl.setAttribute("data-set-event-handler", "true");
|
22
24
|
return true;
|
23
25
|
}
|
24
26
|
});
|
25
27
|
|
26
|
-
initializeInputs();
|
27
28
|
initializeActions();
|
28
29
|
instance.runEffects();
|
29
30
|
}
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { initializeActions } from "actions/initialize-actions";
|
2
|
-
import { initializeInputs } from "inputs/initialize-inputs";
|
3
2
|
|
4
3
|
interface ComponentDefinition {
|
5
4
|
component: string;
|
@@ -42,7 +41,6 @@ const createAndAppendComponent = async (component: ComponentDefinition, element:
|
|
42
41
|
document.addEventListener("DOMContentLoaded", async () => {
|
43
42
|
await initializeComponents();
|
44
43
|
initializeActions();
|
45
|
-
initializeInputs();
|
46
44
|
const event = new Event('clapton:render');
|
47
45
|
document.dispatchEvent(event);
|
48
46
|
});
|
@@ -50,7 +48,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
50
48
|
document.addEventListener("turbo:render", async () => {
|
51
49
|
await initializeComponents();
|
52
50
|
initializeActions();
|
53
|
-
initializeInputs();
|
54
51
|
const event = new Event('clapton:render');
|
55
52
|
document.dispatchEvent(event);
|
56
53
|
});
|
@@ -3,14 +3,14 @@ import { Input } from "./input"
|
|
3
3
|
|
4
4
|
describe("Input", () => {
|
5
5
|
it("returns empty string if no params", () => {
|
6
|
-
expect(new Input({}, "foo", { type: "text" }).renderWrapper).
|
6
|
+
expect(new Input({}, "foo", { type: "text" }).renderWrapper).toMatch(/<input type='text' data-attribute='foo' data-id='.+' value=''\/>/)
|
7
7
|
})
|
8
8
|
|
9
9
|
it("returns attributes and data attributes", () => {
|
10
|
-
expect(new Input({ foo: "bar" }, "foo", { type: "text", id: "1", "data-foo": "bar" }).renderWrapper).
|
10
|
+
expect(new Input({ foo: "bar" }, "foo", { type: "text", id: "1", "data-foo": "bar" }).renderWrapper).toMatch(/<input type='text' id='1' data-foo='bar' data-attribute='foo' data-id='.+' value='bar'\/>/)
|
11
11
|
})
|
12
12
|
|
13
13
|
it("returns attributes and data attributes with custom data attributes", () => {
|
14
|
-
expect(new Input({ foo: "bar" }, "foo", { type: "text", id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).
|
14
|
+
expect(new Input({ foo: "bar" }, "foo", { type: "text", id: "1", data: { foo: { baz: "qux", quux: "corge" } } }).renderWrapper).toMatch(/<input type='text' id='1' data-attribute='foo' data-id='.+' data-foo-baz='qux' data-foo-quux='corge' value='bar'\/>/)
|
15
15
|
})
|
16
16
|
})
|
@@ -10,10 +10,14 @@ export class Input extends Base {
|
|
10
10
|
this.attribute = attribute;
|
11
11
|
this.state = state
|
12
12
|
this.attributes["data-attribute"] = attribute;
|
13
|
+
this.attributes["data-id"] = Math.random().toString(36).substring(2, 10);
|
13
14
|
}
|
14
15
|
|
15
16
|
get renderWrapper(): string {
|
16
17
|
let value = this.state[this.attribute]
|
18
|
+
if (!this.attributes.type) {
|
19
|
+
this.attributes.type = "text"
|
20
|
+
}
|
17
21
|
if (this.attributes.type === "datetime-local" && value) {
|
18
22
|
value = this.datetime_local_value(value)
|
19
23
|
}
|
data/lib/clapton/version.rb
CHANGED
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.
|
4
|
+
version: 0.0.26
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Moeki Kawakami
|
@@ -6757,12 +6757,10 @@ files:
|
|
6757
6757
|
- lib/clapton/javascripts/src/components/text-area.ts
|
6758
6758
|
- lib/clapton/javascripts/src/components/text.spec.ts
|
6759
6759
|
- lib/clapton/javascripts/src/components/text.ts
|
6760
|
-
- lib/clapton/javascripts/src/dom/update-component.ts
|
6761
6760
|
- lib/clapton/javascripts/src/html/html-attributes.spec.ts
|
6762
6761
|
- lib/clapton/javascripts/src/html/html-attributes.ts
|
6763
6762
|
- lib/clapton/javascripts/src/html/split-action-attribute.spec.ts
|
6764
6763
|
- lib/clapton/javascripts/src/html/split-action-attribute.ts
|
6765
|
-
- lib/clapton/javascripts/src/inputs/initialize-inputs.ts
|
6766
6764
|
- lib/clapton/javascripts/src/utils/debounce.ts
|
6767
6765
|
- lib/clapton/javascripts/tsconfig.json
|
6768
6766
|
- lib/clapton/javascripts/vitest.config.js
|
@@ -1,11 +0,0 @@
|
|
1
|
-
import morphdom from "morphdom";
|
2
|
-
|
3
|
-
export const updateComponent = async (component: HTMLElement, state: any, property: string, target: HTMLInputElement) => {
|
4
|
-
state[property] = target.value;
|
5
|
-
const componentName = component.dataset.component as string;
|
6
|
-
const module = await import(`${componentName}`);
|
7
|
-
const ComponentClass = module[componentName] as any;
|
8
|
-
const instance = new ComponentClass(state, component.dataset.id);
|
9
|
-
morphdom(component, instance.renderWrapper);
|
10
|
-
instance.runEffects();
|
11
|
-
};
|
@@ -1,16 +0,0 @@
|
|
1
|
-
import { updateComponent } from "../dom/update-component";
|
2
|
-
|
3
|
-
export const initializeInputs = () => {
|
4
|
-
const inputElements = document.querySelectorAll("[data-attribute]");
|
5
|
-
inputElements.forEach((element: any) => {
|
6
|
-
const attribute = element.getAttribute("data-attribute");
|
7
|
-
const component = element.closest(`[data-component]`) as HTMLElement;
|
8
|
-
const state = JSON.parse(component.getAttribute("data-state") || "{}");
|
9
|
-
if (!attribute || !component) return;
|
10
|
-
if (element.tagName === "INPUT") {
|
11
|
-
element.addEventListener("input", async (event: Event) => {
|
12
|
-
await updateComponent(component, state, attribute, event.target as HTMLInputElement);
|
13
|
-
});
|
14
|
-
}
|
15
|
-
});
|
16
|
-
};
|