@e280/sly 0.2.0-25 → 0.2.0-27
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 +86 -21
- package/package.json +5 -5
- package/s/base/use.ts +5 -0
- package/s/demo/views/fastcount.ts +2 -2
- package/s/dom/attrs/attrs.ts +3 -3
- package/s/dom/attrs/parts/attr-fns.ts +64 -34
- package/s/dom/attrs/parts/attr-proxies.ts +7 -7
- package/s/dom/attrs/parts/attr-spec.ts +7 -7
- package/s/dom/dom.ts +15 -61
- package/s/dom/parts/dom-scope.ts +46 -0
- package/s/dom/parts/el.ts +4 -4
- package/s/dom/parts/elmer.ts +38 -0
- package/s/dom/parts/mk.ts +9 -0
- package/s/dom/parts/queries.ts +26 -0
- package/s/dom/types.ts +5 -0
- package/s/loaders/parts/ascii-anim.ts +2 -2
- package/s/view/types.ts +0 -1
- package/s/view/utils/parts/capsule.ts +2 -2
- package/s/view/utils/parts/chain.ts +10 -3
- package/s/view/utils/parts/context.ts +2 -1
- package/x/base/use.d.ts +2 -0
- package/x/base/use.js +4 -0
- package/x/base/use.js.map +1 -1
- package/x/demo/demo.bundle.min.js +15 -15
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/demo/views/counter.d.ts +4 -4
- package/x/demo/views/fastcount.js +2 -2
- package/x/demo/views/fastcount.js.map +1 -1
- package/x/dom/attrs/attrs.d.ts +3 -0
- package/x/dom/attrs/attrs.js +3 -3
- package/x/dom/attrs/attrs.js.map +1 -1
- package/x/dom/attrs/parts/attr-fns.d.ts +15 -12
- package/x/dom/attrs/parts/attr-fns.js +60 -38
- package/x/dom/attrs/parts/attr-fns.js.map +1 -1
- package/x/dom/attrs/parts/attr-proxies.js +7 -7
- package/x/dom/attrs/parts/attr-proxies.js.map +1 -1
- package/x/dom/attrs/parts/attr-spec.js +7 -7
- package/x/dom/attrs/parts/attr-spec.js.map +1 -1
- package/x/dom/dom.d.ts +11 -27
- package/x/dom/dom.js +15 -48
- package/x/dom/dom.js.map +1 -1
- package/x/dom/parts/dom-scope.d.ts +15 -0
- package/x/dom/parts/dom-scope.js +35 -0
- package/x/dom/parts/dom-scope.js.map +1 -0
- package/x/dom/parts/el.d.ts +2 -2
- package/x/dom/parts/el.js +3 -3
- package/x/dom/parts/el.js.map +1 -1
- package/x/dom/parts/elmer.d.ts +11 -0
- package/x/dom/parts/elmer.js +32 -0
- package/x/dom/parts/elmer.js.map +1 -0
- package/x/dom/parts/mk.d.ts +2 -0
- package/x/dom/parts/mk.js +7 -0
- package/x/dom/parts/mk.js.map +1 -0
- package/x/dom/parts/queries.d.ts +4 -0
- package/x/dom/parts/queries.js +13 -0
- package/x/dom/parts/queries.js.map +1 -0
- package/x/dom/types.d.ts +3 -0
- package/x/index.html +2 -2
- package/x/loaders/parts/ascii-anim.js +2 -2
- package/x/loaders/parts/ascii-anim.js.map +1 -1
- package/x/view/types.d.ts +0 -1
- package/x/view/utils/parts/capsule.js +2 -2
- package/x/view/utils/parts/capsule.js.map +1 -1
- package/x/view/utils/parts/chain.d.ts +5 -3
- package/x/view/utils/parts/chain.js +6 -1
- package/x/view/utils/parts/chain.js.map +1 -1
- package/x/view/utils/parts/context.d.ts +2 -1
- package/x/view/utils/parts/context.js.map +1 -1
- package/s/view/utils/parts/set-attrs.ts +0 -33
- package/x/view/utils/parts/set-attrs.d.ts +0 -3
- package/x/view/utils/parts/set-attrs.js +0 -21
- package/x/view/utils/parts/set-attrs.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
# 🦝 sly
|
|
5
5
|
> *mischievous shadow views*
|
|
6
6
|
|
|
7
|
-
[@e280](https://e280.org/)'s
|
|
7
|
+
[@e280](https://e280.org/)'s new [lit](https://lit.dev/)-based frontend webdev library. *(sly replaces its predecessor, [slate](https://github.com/benevolent-games/slate))*
|
|
8
8
|
|
|
9
|
+
- **✨[shiny](https://shiny.e280.org/)✨** — our wip component library https://shiny.e280.org/
|
|
9
10
|
- 🍋 [**#views**](#views) — shadow-dom'd, hooks-based, componentizable
|
|
10
11
|
- 🪵 [**#base-element**](#base-element) — for a more classical experience
|
|
11
12
|
- 🪄 [**#dom**](#dom) — the "it's not jquery" multitool
|
|
@@ -285,8 +286,15 @@ import {html, css} from "lit"
|
|
|
285
286
|
|
|
286
287
|
v // 123
|
|
287
288
|
```
|
|
289
|
+
- **use.events** — attach event listeners to the element (auto-cleaned up)
|
|
290
|
+
```ts
|
|
291
|
+
use.events({
|
|
292
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
293
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
294
|
+
})
|
|
295
|
+
```
|
|
288
296
|
- **use.attrs** — ergonomic typed html attribute access
|
|
289
|
-
- `use.attrs` is a bit different than
|
|
297
|
+
- `use.attrs` is a bit different than [#dom.attrs](#dom.attrs), just to properly memoize .spec and .on for the render fn
|
|
290
298
|
- use.attrs.spec
|
|
291
299
|
```ts
|
|
292
300
|
const attrs = use.attrs.spec({
|
|
@@ -338,14 +346,14 @@ import {html, css} from "lit"
|
|
|
338
346
|
```
|
|
339
347
|
|
|
340
348
|
### 🍋 "use" recipes
|
|
341
|
-
- make a ticker — mount,
|
|
349
|
+
- make a ticker — mount, cycle, and nap
|
|
342
350
|
```ts
|
|
343
|
-
import {
|
|
351
|
+
import {cycle, nap} from "@e280/stz"
|
|
344
352
|
```
|
|
345
353
|
```ts
|
|
346
354
|
const $seconds = use.signal(0)
|
|
347
355
|
|
|
348
|
-
use.mount(() =>
|
|
356
|
+
use.mount(() => cycle(async() => {
|
|
349
357
|
await nap(1000)
|
|
350
358
|
$seconds.value++
|
|
351
359
|
}))
|
|
@@ -473,6 +481,11 @@ import {dom} from "@e280/sly"
|
|
|
473
481
|
dom(".demo")
|
|
474
482
|
// HTMLElement (or throws)
|
|
475
483
|
```
|
|
484
|
+
```ts
|
|
485
|
+
// alias
|
|
486
|
+
dom.require(".demo")
|
|
487
|
+
// HTMLElement (or throws)
|
|
488
|
+
```
|
|
476
489
|
- `maybe` get an element
|
|
477
490
|
```ts
|
|
478
491
|
dom.maybe(".demo")
|
|
@@ -483,39 +496,83 @@ import {dom} from "@e280/sly"
|
|
|
483
496
|
dom.all(".demo ul li")
|
|
484
497
|
// HTMLElement[]
|
|
485
498
|
```
|
|
486
|
-
|
|
499
|
+
|
|
500
|
+
### 🪄 dom.in scope
|
|
501
|
+
- make a scope
|
|
487
502
|
```ts
|
|
488
|
-
dom
|
|
489
|
-
//
|
|
503
|
+
dom.in(".demo") // selector
|
|
504
|
+
// Dom instance
|
|
490
505
|
```
|
|
491
506
|
```ts
|
|
492
|
-
dom
|
|
493
|
-
//
|
|
507
|
+
dom.in(demoElement) // element
|
|
508
|
+
// Dom instance
|
|
494
509
|
```
|
|
510
|
+
- run queries in that scope
|
|
495
511
|
```ts
|
|
496
|
-
dom(
|
|
497
|
-
|
|
512
|
+
dom.in(demoElement).require(".button")
|
|
513
|
+
```
|
|
514
|
+
```ts
|
|
515
|
+
dom.in(demoElement).maybe(".button")
|
|
516
|
+
```
|
|
517
|
+
```ts
|
|
518
|
+
dom.in(demoElement).all("ol li")
|
|
498
519
|
```
|
|
499
520
|
|
|
500
521
|
### 🪄 dom utilities
|
|
501
|
-
- `register` web components
|
|
522
|
+
- `dom.register` web components
|
|
502
523
|
```ts
|
|
503
524
|
dom.register({MyComponent, AnotherCoolComponent})
|
|
504
525
|
// <my-component>
|
|
505
526
|
// <another-cool-component>
|
|
506
527
|
```
|
|
507
528
|
- `dom.register` automatically dashes the tag names (`MyComponent` becomes `<my-component>`)
|
|
508
|
-
- `render` content into an element
|
|
529
|
+
- `dom.render` content into an element
|
|
509
530
|
```ts
|
|
510
|
-
dom
|
|
531
|
+
dom.render(element, html`<p>hello world</p>`)
|
|
511
532
|
```
|
|
512
533
|
```ts
|
|
513
534
|
dom.in(".demo").render(html`<p>hello world</p>`)
|
|
514
535
|
```
|
|
536
|
+
- `dom.el` little element builder
|
|
515
537
|
```ts
|
|
516
|
-
dom.
|
|
538
|
+
const div = dom.el("div", {"data-whatever": 123, "data-active": true})
|
|
539
|
+
// <div data-whatever="123" data-active></div>
|
|
540
|
+
```
|
|
541
|
+
- `dom.elmer` make an element with a fluent chain
|
|
542
|
+
```ts
|
|
543
|
+
const div = dom.elmer("div")
|
|
544
|
+
.attr("data-whatever", 123)
|
|
545
|
+
.attr("data-active")
|
|
546
|
+
.children("hello world")
|
|
547
|
+
.done()
|
|
548
|
+
// HTMLElement
|
|
517
549
|
```
|
|
518
|
-
- `
|
|
550
|
+
- `dom.mk` make an element with a lit template (returns the first)
|
|
551
|
+
```ts
|
|
552
|
+
const div = dom.mk(html`
|
|
553
|
+
<div data-whatever="123" data-active>
|
|
554
|
+
hello world
|
|
555
|
+
</div>
|
|
556
|
+
`) // HTMLElement
|
|
557
|
+
```
|
|
558
|
+
- `dom.events` <a id="dom.events"></a> to attach event listeners
|
|
559
|
+
```ts
|
|
560
|
+
const detach = dom.events(element, {
|
|
561
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
562
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
563
|
+
})
|
|
564
|
+
```
|
|
565
|
+
```ts
|
|
566
|
+
const detach = dom.in(".demo").events({
|
|
567
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
568
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
569
|
+
})
|
|
570
|
+
```
|
|
571
|
+
```ts
|
|
572
|
+
// unattach those event listeners when you're done
|
|
573
|
+
detach()
|
|
574
|
+
```
|
|
575
|
+
- `dom.attrs` <a id="dom.attrs"></a> to setup a type-happy html attribute helper
|
|
519
576
|
```ts
|
|
520
577
|
const attrs = dom.attrs(element).spec({
|
|
521
578
|
name: String,
|
|
@@ -524,6 +581,13 @@ import {dom} from "@e280/sly"
|
|
|
524
581
|
})
|
|
525
582
|
```
|
|
526
583
|
```ts
|
|
584
|
+
const attrs = dom.in(".demo").attrs.spec({
|
|
585
|
+
name: String,
|
|
586
|
+
count: Number,
|
|
587
|
+
active: Boolean,
|
|
588
|
+
})
|
|
589
|
+
```
|
|
590
|
+
```ts
|
|
527
591
|
attrs.name // "chase"
|
|
528
592
|
attrs.count // 123
|
|
529
593
|
attrs.active // true
|
|
@@ -537,11 +601,12 @@ import {dom} from "@e280/sly"
|
|
|
537
601
|
attrs.name = undefined // removes the attr
|
|
538
602
|
attrs.count = undefined // removes the attr
|
|
539
603
|
```
|
|
540
|
-
or if you wanna be more loosey-
|
|
604
|
+
or if you wanna be more loosey-goosey, skip the spec
|
|
541
605
|
```ts
|
|
542
|
-
dom.
|
|
543
|
-
|
|
544
|
-
|
|
606
|
+
const a = dom.in(".demo").attrs
|
|
607
|
+
a.strings.name = "pimsley"
|
|
608
|
+
a.numbers.count = 125
|
|
609
|
+
a.booleans.active = true
|
|
545
610
|
```
|
|
546
611
|
|
|
547
612
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e280/sly",
|
|
3
|
-
"version": "0.2.0-
|
|
3
|
+
"version": "0.2.0-27",
|
|
4
4
|
"description": "web shadow views",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
"lit": "^3.3.1"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@e280/strata": "^0.2.0
|
|
27
|
-
"@e280/stz": "^0.2.
|
|
26
|
+
"@e280/strata": "^0.2.0",
|
|
27
|
+
"@e280/stz": "^0.2.10"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@e280/science": "^0.1.2",
|
|
31
|
-
"@e280/scute": "^0.1.
|
|
31
|
+
"@e280/scute": "^0.1.1",
|
|
32
32
|
"http-server": "^14.1.1",
|
|
33
33
|
"npm-run-all": "^4.1.5",
|
|
34
|
-
"typescript": "^5.9.
|
|
34
|
+
"typescript": "^5.9.3"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "run-s _clean _ln _tsc _scute",
|
package/s/base/use.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {Op} from "../ops/op.js"
|
|
|
7
7
|
import {Mounts} from "./utils/mounts.js"
|
|
8
8
|
import {UseAttrs} from "./utils/use-attrs.js"
|
|
9
9
|
import {applyStyles} from "./utils/apply-styles.js"
|
|
10
|
+
import { eve, EveSpec } from "../dom/parts/eve.js"
|
|
10
11
|
|
|
11
12
|
export const _wrap = Symbol()
|
|
12
13
|
export const _disconnect = Symbol()
|
|
@@ -90,6 +91,10 @@ export class Use {
|
|
|
90
91
|
return this.life(() => [fn(), () => {}])
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
events(spec: EveSpec) {
|
|
95
|
+
return this.mount(() => eve(this.element, spec))
|
|
96
|
+
}
|
|
97
|
+
|
|
93
98
|
op = (() => {
|
|
94
99
|
const that = this
|
|
95
100
|
function op<V>(f: () => Promise<V>) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import {css, html} from "lit"
|
|
3
|
-
import {nap,
|
|
3
|
+
import {nap, cycle} from "@e280/stz"
|
|
4
4
|
|
|
5
5
|
import {dom} from "../../dom/dom.js"
|
|
6
6
|
import {Use} from "../../base/use.js"
|
|
@@ -16,7 +16,7 @@ export class FastcountElement extends BaseElement {
|
|
|
16
16
|
const {value = 1} = this.attrs
|
|
17
17
|
const $count = use.signal(0)
|
|
18
18
|
|
|
19
|
-
use.mount(() =>
|
|
19
|
+
use.mount(() => cycle(async() => {
|
|
20
20
|
await nap(10)
|
|
21
21
|
await $count($count() + 1)
|
|
22
22
|
}))
|
package/s/dom/attrs/attrs.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
import {AttrSpec} from "../types.js"
|
|
3
3
|
import {onAttrs} from "./parts/on-attrs.js"
|
|
4
|
-
import {attrFns} from "./parts/attr-fns.js"
|
|
5
4
|
import {attrSpec} from "./parts/attr-spec.js"
|
|
6
5
|
import {AttrProxies} from "./parts/attr-proxies.js"
|
|
6
|
+
import {attrGet, attrSet} from "./parts/attr-fns.js"
|
|
7
7
|
|
|
8
8
|
export function attrs(element: HTMLElement) {
|
|
9
9
|
const proxies = new AttrProxies(element)
|
|
@@ -16,6 +16,6 @@ export function attrs(element: HTMLElement) {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
attrs.get =
|
|
20
|
-
attrs.set =
|
|
19
|
+
attrs.get = attrGet
|
|
20
|
+
attrs.set = attrSet
|
|
21
21
|
|
|
@@ -1,38 +1,68 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
2
|
+
import {AttrValue} from "../../types.js"
|
|
3
|
+
|
|
4
|
+
/** get html attributes */
|
|
5
|
+
export const attrGet = {
|
|
6
|
+
string: (e: HTMLElement, key: string) => {
|
|
7
|
+
return e.getAttribute(key) ?? undefined
|
|
8
|
+
},
|
|
9
|
+
number: (e: HTMLElement, key: string) => {
|
|
10
|
+
const raw = e.getAttribute(key)
|
|
11
|
+
return (raw === null || !raw)
|
|
12
|
+
? undefined
|
|
13
|
+
: Number(raw)
|
|
14
|
+
},
|
|
15
|
+
boolean: (e: HTMLElement, key: string) => {
|
|
16
|
+
const raw = e.getAttribute(key)
|
|
17
|
+
return raw !== null
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** set html attributes */
|
|
22
|
+
export const attrSet = {
|
|
23
|
+
string: (e: HTMLElement, key: string, value: string | undefined) => {
|
|
24
|
+
if (value === undefined) e.removeAttribute(key)
|
|
25
|
+
else e.setAttribute(key, value)
|
|
26
|
+
return true
|
|
27
|
+
},
|
|
28
|
+
number: (e: HTMLElement, key: string, value: number | undefined) => {
|
|
29
|
+
if (value === undefined) e.removeAttribute(key)
|
|
30
|
+
else e.setAttribute(key, value.toString())
|
|
31
|
+
return true
|
|
32
|
+
},
|
|
33
|
+
boolean: (e: HTMLElement, key: string, value: boolean | undefined) => {
|
|
34
|
+
if (value) e.setAttribute(key, "")
|
|
35
|
+
else e.removeAttribute(key)
|
|
36
|
+
return true
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
any: (element: HTMLElement, key: string, value: AttrValue) => {
|
|
40
|
+
if (value === undefined || value === null)
|
|
41
|
+
element.removeAttribute(key)
|
|
42
|
+
|
|
43
|
+
else if (typeof value === "string")
|
|
44
|
+
element.setAttribute(key, value)
|
|
45
|
+
|
|
46
|
+
else if (typeof value === "number")
|
|
47
|
+
element.setAttribute(key, value.toString())
|
|
48
|
+
|
|
49
|
+
else if (typeof value === "boolean") {
|
|
50
|
+
if (value === true)
|
|
51
|
+
element.setAttribute(key, "")
|
|
52
|
+
else
|
|
53
|
+
element.removeAttribute(key)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
else console.warn(`invalid attribute "${key}" type is "${typeof value}"`)
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
entries: (element: HTMLElement, entries: Iterable<[key: string, value: AttrValue]>) => {
|
|
60
|
+
for (const [key, value] of entries)
|
|
61
|
+
attrSet.any(element, key, value)
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
record: (element: HTMLElement, record: Record<string, AttrValue>) => {
|
|
65
|
+
return attrSet.entries(element, Object.entries(record))
|
|
36
66
|
},
|
|
37
67
|
}
|
|
38
68
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import {attrGet, attrSet} from "./attr-fns.js"
|
|
3
3
|
|
|
4
4
|
/** a typed proxy accessor for html attributes */
|
|
5
5
|
export class AttrProxies {
|
|
@@ -7,28 +7,28 @@ export class AttrProxies {
|
|
|
7
7
|
|
|
8
8
|
strings = new Proxy({}, {
|
|
9
9
|
get: (_t, key: string) => (
|
|
10
|
-
|
|
10
|
+
attrGet.string(this.element, key)
|
|
11
11
|
),
|
|
12
12
|
set: (_t, key: string, value: string | undefined) => (
|
|
13
|
-
|
|
13
|
+
attrSet.string(this.element, key, value)
|
|
14
14
|
),
|
|
15
15
|
}) as Record<string, string | undefined>
|
|
16
16
|
|
|
17
17
|
numbers = new Proxy({}, {
|
|
18
18
|
get: (_t, key: string) => (
|
|
19
|
-
|
|
19
|
+
attrGet.number(this.element, key)
|
|
20
20
|
),
|
|
21
21
|
set: (_t, key: string, value: number | undefined) => (
|
|
22
|
-
|
|
22
|
+
attrSet.number(this.element, key, value)
|
|
23
23
|
),
|
|
24
24
|
}) as Record<string, number | undefined>
|
|
25
25
|
|
|
26
26
|
booleans = new Proxy({}, {
|
|
27
27
|
get: (_t, key: string) => (
|
|
28
|
-
|
|
28
|
+
attrGet.boolean(this.element, key)
|
|
29
29
|
),
|
|
30
30
|
set: (_t, key: string, value: boolean | undefined) => (
|
|
31
|
-
|
|
31
|
+
attrSet.boolean(this.element, key, value)
|
|
32
32
|
),
|
|
33
33
|
}) as Record<string, boolean | undefined>
|
|
34
34
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
+
import {attrGet, attrSet} from "./attr-fns.js"
|
|
2
3
|
import {AttrSpec, AttrTypes} from "../../types.js"
|
|
3
|
-
import {attrFns} from "./attr-fns.js"
|
|
4
4
|
|
|
5
5
|
/** specify available html attributes and their types and create a proxy accessor */
|
|
6
6
|
export const attrSpec = <A extends AttrSpec>(
|
|
@@ -10,18 +10,18 @@ export const attrSpec = <A extends AttrSpec>(
|
|
|
10
10
|
|
|
11
11
|
get: (_target, key: string) => {
|
|
12
12
|
switch (spec[key]) {
|
|
13
|
-
case String: return
|
|
14
|
-
case Number: return
|
|
15
|
-
case Boolean: return
|
|
13
|
+
case String: return attrGet.string(e, key)
|
|
14
|
+
case Number: return attrGet.number(e, key)
|
|
15
|
+
case Boolean: return attrGet.boolean(e, key)
|
|
16
16
|
default: throw new Error(`invalid attribute type for "${key}"`)
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
|
|
20
20
|
set: (_target, key: string, value: any) => {
|
|
21
21
|
switch (spec[key]) {
|
|
22
|
-
case String: return
|
|
23
|
-
case Number: return
|
|
24
|
-
case Boolean: return
|
|
22
|
+
case String: return attrSet.string(e, key, value)
|
|
23
|
+
case Number: return attrSet.number(e, key, value)
|
|
24
|
+
case Boolean: return attrSet.boolean(e, key, value)
|
|
25
25
|
default: throw new Error(`invalid attribute type for "${key}"`)
|
|
26
26
|
}
|
|
27
27
|
},
|
package/s/dom/dom.ts
CHANGED
|
@@ -1,77 +1,31 @@
|
|
|
1
1
|
|
|
2
2
|
import {render} from "lit"
|
|
3
3
|
import {el} from "./parts/el.js"
|
|
4
|
-
import {
|
|
4
|
+
import {mk} from "./parts/mk.js"
|
|
5
|
+
import {eve} from "./parts/eve.js"
|
|
5
6
|
import {attrs} from "./attrs/attrs.js"
|
|
7
|
+
import {elmer} from "./parts/elmer.js"
|
|
6
8
|
import {Content} from "../view/types.js"
|
|
7
|
-
import {
|
|
9
|
+
import {Dom} from "./parts/dom-scope.js"
|
|
8
10
|
import {register} from "./parts/register.js"
|
|
11
|
+
import {Queryable, Renderable} from "./types.js"
|
|
12
|
+
import {queryAll, queryMaybe, queryRequire} from "./parts/queries.js"
|
|
9
13
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
function require<E extends Element>(
|
|
14
|
-
container: Queryable,
|
|
15
|
-
selector: string,
|
|
16
|
-
) {
|
|
17
|
-
const e = container.querySelector<E>(selector)
|
|
18
|
-
if (!e) throw new Error(`element not found (${selector})`)
|
|
19
|
-
return e
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export class Dom<C extends Queryable> {
|
|
23
|
-
constructor(public element: C) {}
|
|
24
|
-
|
|
25
|
-
in<E extends HTMLElement>(selectorOrElement: string | E) {
|
|
26
|
-
return new Dom<E>(
|
|
27
|
-
(typeof selectorOrElement === "string")
|
|
28
|
-
? require(this.element, selectorOrElement) as E
|
|
29
|
-
: selectorOrElement
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
require<E extends Element = HTMLElement>(selector: string) {
|
|
34
|
-
const e = this.element.querySelector<E>(selector)
|
|
35
|
-
if (!e) throw new Error(`element not found (${selector})`)
|
|
36
|
-
return e
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
maybe<E extends Element = HTMLElement>(selector: string) {
|
|
40
|
-
return this.element.querySelector<E>(selector)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
all<E extends Element = HTMLElement>(selector: string) {
|
|
44
|
-
return Array.from(this.element.querySelectorAll<E>(selector))
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
render(...content: Content[]) {
|
|
48
|
-
return render(content, this.element as Renderable)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
attrs() {
|
|
52
|
-
return attrs(this.element as HTMLElement)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
events(spec: EveSpec) {
|
|
56
|
-
return eve(this.element, spec)
|
|
57
|
-
}
|
|
14
|
+
export function dom<E extends Element>(selector: string, container: Queryable = document): E {
|
|
15
|
+
return queryRequire<E>(selector, container)
|
|
58
16
|
}
|
|
59
17
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export function dom<E extends Queryable>(selectorOrElement: string | E): E | Dom<E> {
|
|
63
|
-
return (typeof selectorOrElement === "string")
|
|
64
|
-
? require(document, selectorOrElement) as E
|
|
65
|
-
: new Dom(selectorOrElement)
|
|
18
|
+
dom.in = <E extends HTMLElement>(selectorOrElement: string | E, container: Queryable = document) => {
|
|
19
|
+
return new Dom(container).in(selectorOrElement)
|
|
66
20
|
}
|
|
67
21
|
|
|
68
|
-
|
|
69
|
-
dom.
|
|
70
|
-
dom.
|
|
71
|
-
dom.maybe = doc.maybe.bind(doc)
|
|
72
|
-
dom.all = doc.all.bind(doc)
|
|
22
|
+
dom.require = queryRequire
|
|
23
|
+
dom.maybe = queryMaybe
|
|
24
|
+
dom.all = queryAll
|
|
73
25
|
|
|
74
26
|
dom.el = el
|
|
27
|
+
dom.elmer = elmer
|
|
28
|
+
dom.mk = mk
|
|
75
29
|
dom.events = eve
|
|
76
30
|
dom.attrs = attrs
|
|
77
31
|
dom.register = register
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
import {render} from "lit"
|
|
3
|
+
import {eve, EveSpec} from "./eve.js"
|
|
4
|
+
import {attrs} from "../attrs/attrs.js"
|
|
5
|
+
import {Content} from "../../view/types.js"
|
|
6
|
+
import {Attrs, Queryable, Renderable} from "../types.js"
|
|
7
|
+
import {queryAll, queryMaybe, queryRequire} from "./queries.js"
|
|
8
|
+
|
|
9
|
+
export class Dom<C extends Queryable> {
|
|
10
|
+
#attrs?: Attrs
|
|
11
|
+
|
|
12
|
+
constructor(public element: C) {}
|
|
13
|
+
|
|
14
|
+
in<E extends HTMLElement>(selectorOrElement: string | E) {
|
|
15
|
+
return new Dom<E>(
|
|
16
|
+
(typeof selectorOrElement === "string")
|
|
17
|
+
? queryRequire(selectorOrElement, this.element) as E
|
|
18
|
+
: selectorOrElement
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
require<E extends Element = HTMLElement>(selector: string) {
|
|
23
|
+
return queryRequire<E>(selector, this.element)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
maybe<E extends Element = HTMLElement>(selector: string) {
|
|
27
|
+
return queryMaybe<E>(selector, this.element)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
all<E extends Element = HTMLElement>(selector: string) {
|
|
31
|
+
return queryAll<E>(selector, this.element)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
render(...content: Content[]) {
|
|
35
|
+
return render(content, this.element as Renderable)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get attrs(): Attrs {
|
|
39
|
+
return this.#attrs ??= attrs(this.element as HTMLElement)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
events(spec: EveSpec) {
|
|
43
|
+
return eve(this.element, spec)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
package/s/dom/parts/el.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
import {AttrValue} from "
|
|
3
|
-
import {
|
|
2
|
+
import {AttrValue} from "../types.js"
|
|
3
|
+
import {attrSet} from "../attrs/parts/attr-fns.js"
|
|
4
4
|
|
|
5
5
|
export function el<E extends HTMLElement>(
|
|
6
6
|
tagName: string,
|
|
7
|
-
attrs: Record<string, AttrValue
|
|
7
|
+
attrs: Record<string, AttrValue> = {},
|
|
8
8
|
) {
|
|
9
9
|
|
|
10
10
|
const element = document.createElement(tagName) as E
|
|
11
|
-
|
|
11
|
+
attrSet.record(element, attrs)
|
|
12
12
|
return element
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
import {AttrValue} from "../types.js"
|
|
3
|
+
import {attrSet} from "../attrs/parts/attr-fns.js"
|
|
4
|
+
|
|
5
|
+
export function elmer<E extends HTMLElement = HTMLElement>(tagName: string) {
|
|
6
|
+
return new Elmer<E>(tagName)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class Elmer<E extends HTMLElement = HTMLElement> {
|
|
10
|
+
#attrs = new Map<string, AttrValue>()
|
|
11
|
+
#children: (Node | string)[] = []
|
|
12
|
+
|
|
13
|
+
constructor(public tagName: string) {}
|
|
14
|
+
|
|
15
|
+
attr(key: string, value: AttrValue = true) {
|
|
16
|
+
this.#attrs.set(key, value)
|
|
17
|
+
return this
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
attrs(record: Record<string, AttrValue>) {
|
|
21
|
+
for (const [key, value] of Object.entries(record))
|
|
22
|
+
this.attr(key, value)
|
|
23
|
+
return this
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
children(...elements: (Node | string)[]) {
|
|
27
|
+
this.#children.push(...elements)
|
|
28
|
+
return this
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
done() {
|
|
32
|
+
const element = document.createElement(this.tagName)
|
|
33
|
+
attrSet.entries(element, this.#attrs)
|
|
34
|
+
element.append(...this.#children)
|
|
35
|
+
return element as E
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|