@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.
Files changed (74) hide show
  1. package/README.md +88 -24
  2. package/package.json +4 -4
  3. package/s/base/use.ts +7 -2
  4. package/s/base/utils/use-attrs.ts +23 -14
  5. package/s/demo/views/fastcount.ts +2 -2
  6. package/s/dom/attrs/attrs.ts +3 -3
  7. package/s/dom/attrs/parts/attr-fns.ts +64 -34
  8. package/s/dom/attrs/parts/attr-proxies.ts +7 -7
  9. package/s/dom/attrs/parts/attr-spec.ts +7 -7
  10. package/s/dom/dom.ts +15 -61
  11. package/s/dom/parts/dom-scope.ts +46 -0
  12. package/s/dom/parts/el.ts +4 -4
  13. package/s/dom/parts/elmer.ts +38 -0
  14. package/s/dom/parts/mk.ts +9 -0
  15. package/s/dom/parts/queries.ts +26 -0
  16. package/s/dom/types.ts +5 -0
  17. package/s/loaders/parts/ascii-anim.ts +2 -2
  18. package/s/view/types.ts +0 -1
  19. package/s/view/utils/parts/capsule.ts +2 -2
  20. package/s/view/utils/parts/chain.ts +3 -2
  21. package/s/view/utils/parts/context.ts +2 -1
  22. package/x/base/use.d.ts +2 -0
  23. package/x/base/use.js +6 -2
  24. package/x/base/use.js.map +1 -1
  25. package/x/base/utils/use-attrs.d.ts +9 -9
  26. package/x/base/utils/use-attrs.js +14 -15
  27. package/x/base/utils/use-attrs.js.map +1 -1
  28. package/x/demo/demo.bundle.min.js +15 -15
  29. package/x/demo/demo.bundle.min.js.map +4 -4
  30. package/x/demo/views/fastcount.js +2 -2
  31. package/x/demo/views/fastcount.js.map +1 -1
  32. package/x/dom/attrs/attrs.d.ts +3 -0
  33. package/x/dom/attrs/attrs.js +3 -3
  34. package/x/dom/attrs/attrs.js.map +1 -1
  35. package/x/dom/attrs/parts/attr-fns.d.ts +15 -12
  36. package/x/dom/attrs/parts/attr-fns.js +60 -38
  37. package/x/dom/attrs/parts/attr-fns.js.map +1 -1
  38. package/x/dom/attrs/parts/attr-proxies.js +7 -7
  39. package/x/dom/attrs/parts/attr-proxies.js.map +1 -1
  40. package/x/dom/attrs/parts/attr-spec.js +7 -7
  41. package/x/dom/attrs/parts/attr-spec.js.map +1 -1
  42. package/x/dom/dom.d.ts +11 -27
  43. package/x/dom/dom.js +15 -48
  44. package/x/dom/dom.js.map +1 -1
  45. package/x/dom/parts/dom-scope.d.ts +15 -0
  46. package/x/dom/parts/dom-scope.js +35 -0
  47. package/x/dom/parts/dom-scope.js.map +1 -0
  48. package/x/dom/parts/el.d.ts +2 -2
  49. package/x/dom/parts/el.js +3 -3
  50. package/x/dom/parts/el.js.map +1 -1
  51. package/x/dom/parts/elmer.d.ts +11 -0
  52. package/x/dom/parts/elmer.js +32 -0
  53. package/x/dom/parts/elmer.js.map +1 -0
  54. package/x/dom/parts/mk.d.ts +2 -0
  55. package/x/dom/parts/mk.js +7 -0
  56. package/x/dom/parts/mk.js.map +1 -0
  57. package/x/dom/parts/queries.d.ts +4 -0
  58. package/x/dom/parts/queries.js +13 -0
  59. package/x/dom/parts/queries.js.map +1 -0
  60. package/x/dom/types.d.ts +3 -0
  61. package/x/index.html +2 -2
  62. package/x/loaders/parts/ascii-anim.js +2 -2
  63. package/x/loaders/parts/ascii-anim.js.map +1 -1
  64. package/x/view/types.d.ts +0 -1
  65. package/x/view/utils/parts/capsule.js +2 -2
  66. package/x/view/utils/parts/capsule.js.map +1 -1
  67. package/x/view/utils/parts/chain.d.ts +3 -2
  68. package/x/view/utils/parts/chain.js.map +1 -1
  69. package/x/view/utils/parts/context.d.ts +2 -1
  70. package/x/view/utils/parts/context.js.map +1 -1
  71. package/s/view/utils/parts/set-attrs.ts +0 -33
  72. package/x/view/utils/parts/set-attrs.d.ts +0 -3
  73. package/x/view/utils/parts/set-attrs.js +0 -21
  74. 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 shiny new [lit](https://lit.dev/)-based frontend webdev library. *(sly replaces its predecessor, [slate](https://github.com/benevolent-games/slate))*
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 a bit different than `dom.attrs`, just to properly memoize .spec and .on for the render fn
290
- - use.attrs.spec
297
+ - `use.attrs` is similar to [#dom.attrs](#dom.attrs)
291
298
  ```ts
292
- const attrs = use.attrs.spec({
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.(strings/numbers/booleans)
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, repeat, and nap
348
+ - make a ticker — mount, cycle, and nap
342
349
  ```ts
343
- import {repeat, nap} from "@e280/stz"
350
+ import {cycle, nap} from "@e280/stz"
344
351
  ```
345
352
  ```ts
346
353
  const $seconds = use.signal(0)
347
354
 
348
- use.mount(() => repeat(async() => {
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
- - scoped to an element
498
+
499
+ ### 🪄 dom.in scope
500
+ - make a scope
487
501
  ```ts
488
- dom(element).require("li")
489
- // HTMLElement (or throws)
502
+ dom.in(".demo") // selector
503
+ // Dom instance
490
504
  ```
491
505
  ```ts
492
- dom(element).maybe("li")
493
- // HTMLElement | undefined
506
+ dom.in(demoElement) // element
507
+ // Dom instance
494
508
  ```
509
+ - run queries in that scope
495
510
  ```ts
496
- dom(element).all("li")
497
- // HTMLElement[]
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(element).render(html`<p>hello world</p>`)
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.render(element, html`<p>hello world</p>`)
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
- - `attrs` <a id="dom.attrs"></a> to setup a type-happy html attribute helper
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-goosy, skip the spec
603
+ or if you wanna be more loosey-goosey, skip the spec
541
604
  ```ts
542
- dom.attrs(element).strings.name = "pimsley"
543
- dom.attrs(element).numbers.count = 125
544
- dom.attrs(element).booleans.active = true
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-26",
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-14",
27
- "@e280/stz": "^0.2.9"
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.0",
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 {UseAttrs} from "./utils/use-attrs.js"
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 = new UseAttrs(this)
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 {Attrs, AttrSpec} from "../../dom/types.js"
4
+ import {AttrSpec, AttrTypes} from "../../dom/types.js"
5
5
 
6
- export class UseAttrs {
7
- #use: Use
8
- #attrs: Attrs
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
- constructor(use: Use) {
11
- this.#use = use
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
- get strings() { return this.#attrs.strings }
16
- get numbers() { return this.#attrs.numbers }
17
- get booleans() { return this.#attrs.booleans }
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 this.#use.once(() => this.#attrs.spec(spec))
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 this.#use.mount(() => this.#attrs.on(fn))
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, repeat} from "@e280/stz"
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(() => repeat(async() => {
19
+ use.mount(() => cycle(async() => {
20
20
  await nap(10)
21
21
  await $count($count() + 1)
22
22
  }))
@@ -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 = attrFns.get
20
- attrs.set = attrFns.set
19
+ attrs.get = attrGet
20
+ attrs.set = attrSet
21
21
 
@@ -1,38 +1,68 @@
1
1
 
2
- /** fns for getting and setting html attributes of various types */
3
- export const attrFns = {
4
- get: {
5
- string: (e: HTMLElement, key: string) => {
6
- return e.getAttribute(key) ?? undefined
7
- },
8
- number: (e: HTMLElement, key: string) => {
9
- const raw = e.getAttribute(key)
10
- return (raw === null || !raw)
11
- ? undefined
12
- : Number(raw)
13
- },
14
- boolean: (e: HTMLElement, key: string) => {
15
- const raw = e.getAttribute(key)
16
- return raw !== null
17
- },
18
- },
19
-
20
- set: {
21
- string: (e: HTMLElement, key: string, value: string | undefined) => {
22
- if (value === undefined) e.removeAttribute(key)
23
- else e.setAttribute(key, value)
24
- return true
25
- },
26
- number: (e: HTMLElement, key: string, value: number | undefined) => {
27
- if (value === undefined) e.removeAttribute(key)
28
- else e.setAttribute(key, value.toString())
29
- return true
30
- },
31
- boolean: (e: HTMLElement, key: string, value: boolean | undefined) => {
32
- if (value) e.setAttribute(key, "")
33
- else e.removeAttribute(key)
34
- return true
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 {attrFns} from "./attr-fns.js"
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
- attrFns.get.string(this.element, key)
10
+ attrGet.string(this.element, key)
11
11
  ),
12
12
  set: (_t, key: string, value: string | undefined) => (
13
- attrFns.set.string(this.element, key, value)
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
- attrFns.get.number(this.element, key)
19
+ attrGet.number(this.element, key)
20
20
  ),
21
21
  set: (_t, key: string, value: number | undefined) => (
22
- attrFns.set.number(this.element, key, value)
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
- attrFns.get.boolean(this.element, key)
28
+ attrGet.boolean(this.element, key)
29
29
  ),
30
30
  set: (_t, key: string, value: boolean | undefined) => (
31
- attrFns.set.boolean(this.element, key, value)
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 attrFns.get.string(e, key)
14
- case Number: return attrFns.get.number(e, key)
15
- case Boolean: return attrFns.get.boolean(e, key)
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 attrFns.set.string(e, key, value)
23
- case Number: return attrFns.set.number(e, key, value)
24
- case Boolean: return attrFns.set.boolean(e, key, value)
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 {AttrSpec} from "./types.js"
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 {eve, EveSpec} from "./parts/eve.js"
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 type Renderable = HTMLElement | ShadowRoot | DocumentFragment
11
- export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment
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
- export function dom<E extends Queryable>(selector: string): E
61
- export function dom<E extends Queryable>(element: E): Dom<E>
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
- const doc = new Dom(document)
69
- dom.in = doc.in.bind(doc)
70
- dom.require = doc.require.bind(doc)
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
+