clapton 0.0.25 → 0.0.26
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.
- 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
|
-
};
|