@e280/sly 0.2.0-26 → 0.2.0-28
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 +88 -24
- package/package.json +4 -4
- package/s/base/use.ts +7 -2
- package/s/base/utils/use-attrs.ts +23 -14
- 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 +3 -2
- package/s/view/utils/parts/context.ts +2 -1
- package/x/base/use.d.ts +2 -0
- package/x/base/use.js +6 -2
- package/x/base/use.js.map +1 -1
- package/x/base/utils/use-attrs.d.ts +9 -9
- package/x/base/utils/use-attrs.js +14 -15
- package/x/base/utils/use-attrs.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/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 +3 -2
- 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,11 +286,17 @@ 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
|
|
290
|
-
- use.attrs.spec
|
|
297
|
+
- `use.attrs` is similar to [#dom.attrs](#dom.attrs)
|
|
291
298
|
```ts
|
|
292
|
-
const attrs = use.attrs
|
|
299
|
+
const attrs = use.attrs({
|
|
293
300
|
name: String,
|
|
294
301
|
count: Number,
|
|
295
302
|
active: Boolean,
|
|
@@ -300,7 +307,7 @@ import {html, css} from "lit"
|
|
|
300
307
|
attrs.count // 123
|
|
301
308
|
attrs.active // true
|
|
302
309
|
```
|
|
303
|
-
- use.attrs.
|
|
310
|
+
- use.attrs.{strings/numbers/booleans}
|
|
304
311
|
```ts
|
|
305
312
|
use.attrs.strings.name // "chase"
|
|
306
313
|
use.attrs.numbers.count // 123
|
|
@@ -338,14 +345,14 @@ import {html, css} from "lit"
|
|
|
338
345
|
```
|
|
339
346
|
|
|
340
347
|
### 🍋 "use" recipes
|
|
341
|
-
- make a ticker — mount,
|
|
348
|
+
- make a ticker — mount, cycle, and nap
|
|
342
349
|
```ts
|
|
343
|
-
import {
|
|
350
|
+
import {cycle, nap} from "@e280/stz"
|
|
344
351
|
```
|
|
345
352
|
```ts
|
|
346
353
|
const $seconds = use.signal(0)
|
|
347
354
|
|
|
348
|
-
use.mount(() =>
|
|
355
|
+
use.mount(() => cycle(async() => {
|
|
349
356
|
await nap(1000)
|
|
350
357
|
$seconds.value++
|
|
351
358
|
}))
|
|
@@ -473,6 +480,11 @@ import {dom} from "@e280/sly"
|
|
|
473
480
|
dom(".demo")
|
|
474
481
|
// HTMLElement (or throws)
|
|
475
482
|
```
|
|
483
|
+
```ts
|
|
484
|
+
// alias
|
|
485
|
+
dom.require(".demo")
|
|
486
|
+
// HTMLElement (or throws)
|
|
487
|
+
```
|
|
476
488
|
- `maybe` get an element
|
|
477
489
|
```ts
|
|
478
490
|
dom.maybe(".demo")
|
|
@@ -483,39 +495,83 @@ import {dom} from "@e280/sly"
|
|
|
483
495
|
dom.all(".demo ul li")
|
|
484
496
|
// HTMLElement[]
|
|
485
497
|
```
|
|
486
|
-
|
|
498
|
+
|
|
499
|
+
### 🪄 dom.in scope
|
|
500
|
+
- make a scope
|
|
487
501
|
```ts
|
|
488
|
-
dom
|
|
489
|
-
//
|
|
502
|
+
dom.in(".demo") // selector
|
|
503
|
+
// Dom instance
|
|
490
504
|
```
|
|
491
505
|
```ts
|
|
492
|
-
dom
|
|
493
|
-
//
|
|
506
|
+
dom.in(demoElement) // element
|
|
507
|
+
// Dom instance
|
|
494
508
|
```
|
|
509
|
+
- run queries in that scope
|
|
495
510
|
```ts
|
|
496
|
-
dom(
|
|
497
|
-
|
|
511
|
+
dom.in(demoElement).require(".button")
|
|
512
|
+
```
|
|
513
|
+
```ts
|
|
514
|
+
dom.in(demoElement).maybe(".button")
|
|
515
|
+
```
|
|
516
|
+
```ts
|
|
517
|
+
dom.in(demoElement).all("ol li")
|
|
498
518
|
```
|
|
499
519
|
|
|
500
520
|
### 🪄 dom utilities
|
|
501
|
-
- `register` web components
|
|
521
|
+
- `dom.register` web components
|
|
502
522
|
```ts
|
|
503
523
|
dom.register({MyComponent, AnotherCoolComponent})
|
|
504
524
|
// <my-component>
|
|
505
525
|
// <another-cool-component>
|
|
506
526
|
```
|
|
507
527
|
- `dom.register` automatically dashes the tag names (`MyComponent` becomes `<my-component>`)
|
|
508
|
-
- `render` content into an element
|
|
528
|
+
- `dom.render` content into an element
|
|
509
529
|
```ts
|
|
510
|
-
dom
|
|
530
|
+
dom.render(element, html`<p>hello world</p>`)
|
|
511
531
|
```
|
|
512
532
|
```ts
|
|
513
533
|
dom.in(".demo").render(html`<p>hello world</p>`)
|
|
514
534
|
```
|
|
535
|
+
- `dom.el` little element builder
|
|
515
536
|
```ts
|
|
516
|
-
dom.
|
|
537
|
+
const div = dom.el("div", {"data-whatever": 123, "data-active": true})
|
|
538
|
+
// <div data-whatever="123" data-active></div>
|
|
539
|
+
```
|
|
540
|
+
- `dom.elmer` make an element with a fluent chain
|
|
541
|
+
```ts
|
|
542
|
+
const div = dom.elmer("div")
|
|
543
|
+
.attr("data-whatever", 123)
|
|
544
|
+
.attr("data-active")
|
|
545
|
+
.children("hello world")
|
|
546
|
+
.done()
|
|
547
|
+
// HTMLElement
|
|
517
548
|
```
|
|
518
|
-
- `
|
|
549
|
+
- `dom.mk` make an element with a lit template (returns the first)
|
|
550
|
+
```ts
|
|
551
|
+
const div = dom.mk(html`
|
|
552
|
+
<div data-whatever="123" data-active>
|
|
553
|
+
hello world
|
|
554
|
+
</div>
|
|
555
|
+
`) // HTMLElement
|
|
556
|
+
```
|
|
557
|
+
- `dom.events` <a id="dom.events"></a> to attach event listeners
|
|
558
|
+
```ts
|
|
559
|
+
const detach = dom.events(element, {
|
|
560
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
561
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
562
|
+
})
|
|
563
|
+
```
|
|
564
|
+
```ts
|
|
565
|
+
const detach = dom.in(".demo").events({
|
|
566
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
567
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
568
|
+
})
|
|
569
|
+
```
|
|
570
|
+
```ts
|
|
571
|
+
// unattach those event listeners when you're done
|
|
572
|
+
detach()
|
|
573
|
+
```
|
|
574
|
+
- `dom.attrs` <a id="dom.attrs"></a> to setup a type-happy html attribute helper
|
|
519
575
|
```ts
|
|
520
576
|
const attrs = dom.attrs(element).spec({
|
|
521
577
|
name: String,
|
|
@@ -524,6 +580,13 @@ import {dom} from "@e280/sly"
|
|
|
524
580
|
})
|
|
525
581
|
```
|
|
526
582
|
```ts
|
|
583
|
+
const attrs = dom.in(".demo").attrs.spec({
|
|
584
|
+
name: String,
|
|
585
|
+
count: Number,
|
|
586
|
+
active: Boolean,
|
|
587
|
+
})
|
|
588
|
+
```
|
|
589
|
+
```ts
|
|
527
590
|
attrs.name // "chase"
|
|
528
591
|
attrs.count // 123
|
|
529
592
|
attrs.active // true
|
|
@@ -537,11 +600,12 @@ import {dom} from "@e280/sly"
|
|
|
537
600
|
attrs.name = undefined // removes the attr
|
|
538
601
|
attrs.count = undefined // removes the attr
|
|
539
602
|
```
|
|
540
|
-
or if you wanna be more loosey-
|
|
603
|
+
or if you wanna be more loosey-goosey, skip the spec
|
|
541
604
|
```ts
|
|
542
|
-
dom.
|
|
543
|
-
|
|
544
|
-
|
|
605
|
+
const a = dom.in(".demo").attrs
|
|
606
|
+
a.strings.name = "pimsley"
|
|
607
|
+
a.numbers.count = 125
|
|
608
|
+
a.booleans.active = true
|
|
545
609
|
```
|
|
546
610
|
|
|
547
611
|
|
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-28",
|
|
4
4
|
"description": "web shadow views",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,12 +23,12 @@
|
|
|
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
34
|
"typescript": "^5.9.3"
|
package/s/base/use.ts
CHANGED
|
@@ -5,8 +5,9 @@ import {signal, SignalOptions} from "@e280/strata/signals"
|
|
|
5
5
|
|
|
6
6
|
import {Op} from "../ops/op.js"
|
|
7
7
|
import {Mounts} from "./utils/mounts.js"
|
|
8
|
-
import {
|
|
8
|
+
import {eve, EveSpec} from "../dom/parts/eve.js"
|
|
9
9
|
import {applyStyles} from "./utils/apply-styles.js"
|
|
10
|
+
import {useAttrs, UseAttrs} from "./utils/use-attrs.js"
|
|
10
11
|
|
|
11
12
|
export const _wrap = Symbol()
|
|
12
13
|
export const _disconnect = Symbol()
|
|
@@ -44,7 +45,7 @@ export class Use {
|
|
|
44
45
|
public renderNow: () => void,
|
|
45
46
|
public render: () => Promise<void>,
|
|
46
47
|
) {
|
|
47
|
-
this.attrs =
|
|
48
|
+
this.attrs = useAttrs(this)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
get renderCount() {
|
|
@@ -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,27 +1,36 @@
|
|
|
1
1
|
|
|
2
2
|
import {Use} from "../use.js"
|
|
3
3
|
import {dom} from "../../dom/dom.js"
|
|
4
|
-
import {
|
|
4
|
+
import {AttrSpec, AttrTypes} from "../../dom/types.js"
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export type UseAttrs = {
|
|
7
|
+
<A extends AttrSpec>(spec: A): AttrTypes<A>
|
|
8
|
+
strings: Record<string, undefined | string>
|
|
9
|
+
numbers: Record<string, undefined | number>
|
|
10
|
+
booleans: Record<string, undefined | boolean>
|
|
11
|
+
spec<A extends AttrSpec>(spec: A): AttrTypes<A>
|
|
12
|
+
on(fn: () => void): void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useAttrs(use: Use): UseAttrs {
|
|
16
|
+
const attrs = dom.attrs(use.element)
|
|
9
17
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
this.#attrs = dom.attrs(use.element)
|
|
18
|
+
function attrsFn<A extends AttrSpec>(spec: A) {
|
|
19
|
+
return use.once(() => attrs.spec<A>(spec))
|
|
13
20
|
}
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
attrsFn.strings = attrs.strings
|
|
23
|
+
attrsFn.numbers = attrs.numbers
|
|
24
|
+
attrsFn.booleans = attrs.booleans
|
|
18
25
|
|
|
19
|
-
spec<A extends AttrSpec>(spec: A) {
|
|
20
|
-
return
|
|
26
|
+
attrsFn.spec = <A extends AttrSpec>(spec: A) => {
|
|
27
|
+
return use.once(() => attrs.spec<A>(spec))
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
on(fn: () => void) {
|
|
24
|
-
return
|
|
30
|
+
attrsFn.on = (fn: () => void) => {
|
|
31
|
+
return use.mount(() => attrs.on(fn))
|
|
25
32
|
}
|
|
33
|
+
|
|
34
|
+
return attrsFn
|
|
26
35
|
}
|
|
27
36
|
|
|
@@ -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
|
+
|