@e280/sly 0.2.0-9 → 0.2.0
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 +363 -124
- package/package.json +14 -7
- package/s/{views/base-element.ts → base/element.ts} +18 -10
- package/s/base/index.ts +6 -0
- package/s/{views → base}/use.ts +15 -6
- package/s/{views → base}/utils/reactor.ts +13 -4
- package/s/base/utils/states.ts +49 -0
- package/s/base/utils/use-attrs.ts +36 -0
- package/s/demo/demo.bundle.ts +6 -19
- package/s/demo/views/counter.ts +14 -25
- package/s/demo/views/demo.ts +9 -16
- package/s/demo/views/{incredi.ts → fastcount.ts} +5 -5
- package/s/demo/views/loaders.ts +7 -7
- package/s/dom/attrs/attrs.ts +6 -6
- package/s/dom/attrs/parts/attr-fns.ts +64 -34
- package/s/dom/attrs/parts/attr-proxies.ts +10 -10
- package/s/dom/attrs/parts/attr-spec.ts +7 -7
- package/s/dom/dom.ts +19 -57
- package/s/dom/index.ts +4 -0
- package/s/dom/parts/dom-scope.ts +46 -0
- package/s/dom/parts/el.ts +14 -0
- package/s/dom/parts/elmer.ts +38 -0
- package/s/dom/parts/eve.ts +24 -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/index.html.ts +4 -4
- package/s/index.ts +7 -17
- package/s/loaders/index.barrel.ts +10 -0
- package/s/loaders/index.ts +4 -0
- package/s/loaders/make.ts +14 -0
- package/s/loaders/mock.ts +11 -0
- package/s/{ops/loaders → loaders}/parts/anims.ts +1 -1
- package/s/{ops/loaders → loaders}/parts/ascii-anim.ts +6 -5
- package/s/{ops/loaders → loaders}/parts/error-display.ts +2 -2
- package/s/loaders/types.ts +6 -0
- package/s/loot/index.barrel.ts +5 -0
- package/s/loot/index.ts +2 -3
- package/s/ops/index.ts +5 -0
- package/s/ops/op.ts +1 -0
- package/s/spa/index.barrel.ts +6 -0
- package/s/spa/index.ts +4 -0
- package/s/spa/plumbing/braces.ts +76 -0
- package/s/spa/plumbing/primitives.ts +85 -0
- package/s/spa/plumbing/router-core.ts +49 -0
- package/s/spa/plumbing/types.ts +45 -0
- package/s/spa/router.ts +49 -0
- package/s/spa/spa.test.ts +91 -0
- package/s/tests.test.ts +4 -1
- package/s/view/index.ts +7 -0
- package/s/view/types.ts +39 -0
- package/s/view/utils/contextualize.ts +45 -0
- package/s/view/utils/make-component.ts +34 -0
- package/s/view/utils/make-view.ts +48 -0
- package/s/view/utils/parts/capsule.ts +67 -0
- package/s/view/utils/parts/chain.ts +40 -0
- package/s/view/utils/parts/context.ts +11 -0
- package/s/view/utils/parts/directive.ts +29 -0
- package/s/view/utils/parts/sly-view.ts +15 -0
- package/s/view/view.ts +24 -0
- package/x/base/css-reset.js.map +1 -0
- package/x/base/element.d.ts +19 -0
- package/x/{views/base-element.js → base/element.js} +14 -6
- package/x/base/element.js.map +1 -0
- package/x/base/index.d.ts +4 -0
- package/x/base/index.js +5 -0
- package/x/base/index.js.map +1 -0
- package/x/{views → base}/use.d.ts +6 -2
- package/x/{views → base}/use.js +12 -4
- package/x/base/use.js.map +1 -0
- package/x/base/utils/apply-styles.js.map +1 -0
- package/x/base/utils/attr-watcher.js.map +1 -0
- package/x/base/utils/mounts.js.map +1 -0
- package/x/{views → base}/utils/reactor.d.ts +0 -1
- package/x/{views → base}/utils/reactor.js +10 -3
- package/x/base/utils/reactor.js.map +1 -0
- package/x/base/utils/states.d.ts +13 -0
- package/x/base/utils/states.js +41 -0
- package/x/base/utils/states.js.map +1 -0
- package/x/base/utils/use-attrs.d.ts +11 -0
- package/x/base/utils/use-attrs.js +18 -0
- package/x/base/utils/use-attrs.js.map +1 -0
- package/x/demo/demo.bundle.js +6 -16
- package/x/demo/demo.bundle.js.map +1 -1
- package/x/demo/demo.bundle.min.js +16 -26
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/demo/views/counter.d.ts +370 -3
- package/x/demo/views/counter.js +14 -23
- package/x/demo/views/counter.js.map +1 -1
- package/x/demo/views/demo.d.ts +4 -1
- package/x/demo/views/demo.js +9 -13
- package/x/demo/views/demo.js.map +1 -1
- package/x/demo/views/{incredi.d.ts → fastcount.d.ts} +3 -3
- package/x/demo/views/{incredi.js → fastcount.js} +5 -5
- package/x/demo/views/fastcount.js.map +1 -0
- package/x/demo/views/loaders.js +6 -6
- package/x/demo/views/loaders.js.map +1 -1
- package/x/dom/attrs/attrs.d.ts +6 -3
- package/x/dom/attrs/attrs.js +6 -6
- 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.d.ts +3 -3
- package/x/dom/attrs/parts/attr-proxies.js +10 -10
- 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 +14 -26
- package/x/dom/dom.js +18 -44
- package/x/dom/dom.js.map +1 -1
- package/x/dom/index.d.ts +2 -0
- package/x/dom/index.js +3 -0
- package/x/dom/index.js.map +1 -0
- 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 -0
- package/x/dom/parts/el.js +7 -0
- package/x/dom/parts/el.js.map +1 -0
- 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/eve.d.ts +7 -0
- package/x/dom/parts/eve.js +16 -0
- package/x/dom/parts/eve.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.d.ts +7 -14
- package/x/index.html +6 -6
- package/x/index.html.js +4 -4
- package/x/index.js +7 -14
- package/x/index.js.map +1 -1
- package/x/loaders/index.barrel.d.ts +7 -0
- package/x/loaders/index.barrel.js +7 -0
- package/x/loaders/index.barrel.js.map +1 -0
- package/x/loaders/index.d.ts +2 -0
- package/x/loaders/index.js +2 -0
- package/x/loaders/index.js.map +1 -0
- package/x/loaders/make.d.ts +3 -0
- package/x/loaders/make.js +6 -0
- package/x/loaders/make.js.map +1 -0
- package/x/loaders/mock.d.ts +2 -0
- package/x/loaders/mock.js +8 -0
- package/x/loaders/mock.js.map +1 -0
- package/x/{ops/loaders → loaders}/parts/anims.d.ts +1 -1
- package/x/loaders/parts/anims.js.map +1 -0
- package/x/{ops/loaders → loaders}/parts/ascii-anim.d.ts +2 -2
- package/x/{ops/loaders → loaders}/parts/ascii-anim.js +4 -4
- package/x/loaders/parts/ascii-anim.js.map +1 -0
- package/x/loaders/parts/error-display.d.ts +1 -0
- package/x/{ops/loaders → loaders}/parts/error-display.js +2 -2
- package/x/loaders/parts/error-display.js.map +1 -0
- package/x/loaders/types.d.ts +3 -0
- package/x/loaders/types.js.map +1 -0
- package/x/loot/index.barrel.d.ts +3 -0
- package/x/loot/index.barrel.js +4 -0
- package/x/loot/index.barrel.js.map +1 -0
- package/x/loot/index.d.ts +2 -3
- package/x/loot/index.js +1 -3
- package/x/loot/index.js.map +1 -1
- package/x/ops/index.d.ts +3 -0
- package/x/ops/index.js +4 -0
- package/x/ops/index.js.map +1 -0
- package/x/ops/op.js +1 -0
- package/x/ops/op.js.map +1 -1
- package/x/spa/index.barrel.d.ts +4 -0
- package/x/spa/index.barrel.js +3 -0
- package/x/spa/index.barrel.js.map +1 -0
- package/x/spa/index.d.ts +2 -0
- package/x/spa/index.js +2 -0
- package/x/spa/index.js.map +1 -0
- package/x/spa/plumbing/braces.d.ts +12 -0
- package/x/spa/plumbing/braces.js +55 -0
- package/x/spa/plumbing/braces.js.map +1 -0
- package/x/spa/plumbing/primitives.d.ts +22 -0
- package/x/spa/plumbing/primitives.js +65 -0
- package/x/spa/plumbing/primitives.js.map +1 -0
- package/x/spa/plumbing/router-core.d.ts +13 -0
- package/x/spa/plumbing/router-core.js +38 -0
- package/x/spa/plumbing/router-core.js.map +1 -0
- package/x/spa/plumbing/types.d.ts +35 -0
- package/x/spa/plumbing/types.js +2 -0
- package/x/spa/plumbing/types.js.map +1 -0
- package/x/spa/router.d.ts +13 -0
- package/x/spa/router.js +39 -0
- package/x/spa/router.js.map +1 -0
- package/x/spa/spa.test.d.ts +15 -0
- package/x/spa/spa.test.js +78 -0
- package/x/spa/spa.test.js.map +1 -0
- package/x/tests.test.js +4 -1
- package/x/tests.test.js.map +1 -1
- package/x/view/index.d.ts +5 -0
- package/x/view/index.js +6 -0
- package/x/view/index.js.map +1 -0
- package/x/view/types.d.ts +21 -0
- package/x/view/types.js +2 -0
- package/x/{views → view}/types.js.map +1 -1
- package/x/view/utils/contextualize.d.ts +13 -0
- package/x/view/utils/contextualize.js +18 -0
- package/x/view/utils/contextualize.js.map +1 -0
- package/x/view/utils/make-component.d.ts +5 -0
- package/x/view/utils/make-component.js +17 -0
- package/x/view/utils/make-component.js.map +1 -0
- package/x/view/utils/make-view.d.ts +2 -0
- package/x/view/utils/make-view.js +24 -0
- package/x/view/utils/make-view.js.map +1 -0
- package/x/view/utils/parts/capsule.d.ts +13 -0
- package/x/view/utils/parts/capsule.js +49 -0
- package/x/view/utils/parts/capsule.js.map +1 -0
- package/x/view/utils/parts/chain.d.ts +13 -0
- package/x/view/utils/parts/chain.js +26 -0
- package/x/view/utils/parts/chain.js.map +1 -0
- package/x/view/utils/parts/context.d.ts +9 -0
- package/x/view/utils/parts/context.js +10 -0
- package/x/view/utils/parts/context.js.map +1 -0
- package/x/view/utils/parts/directive.d.ts +5 -0
- package/x/view/utils/parts/directive.js +18 -0
- package/x/view/utils/parts/directive.js.map +1 -0
- package/x/view/utils/parts/sly-view.d.ts +5 -0
- package/x/view/utils/parts/sly-view.js +13 -0
- package/x/view/utils/parts/sly-view.js.map +1 -0
- package/x/view/view.d.ts +11 -0
- package/x/view/view.js +15 -0
- package/x/view/view.js.map +1 -0
- package/s/demo/views/divine.ts +0 -22
- package/s/ops/loaders/make-loader.ts +0 -18
- package/s/views/types.ts +0 -49
- package/s/views/utils/apply-attrs.ts +0 -33
- package/s/views/view.ts +0 -185
- package/x/demo/views/divine.d.ts +0 -8
- package/x/demo/views/divine.js +0 -19
- package/x/demo/views/divine.js.map +0 -1
- package/x/demo/views/incredi.js.map +0 -1
- package/x/ops/loaders/make-loader.d.ts +0 -5
- package/x/ops/loaders/make-loader.js +0 -7
- package/x/ops/loaders/make-loader.js.map +0 -1
- package/x/ops/loaders/parts/anims.js.map +0 -1
- package/x/ops/loaders/parts/ascii-anim.js.map +0 -1
- package/x/ops/loaders/parts/error-display.d.ts +0 -1
- package/x/ops/loaders/parts/error-display.js.map +0 -1
- package/x/views/base-element.d.ts +0 -14
- package/x/views/base-element.js.map +0 -1
- package/x/views/css-reset.js.map +0 -1
- package/x/views/types.d.ts +0 -36
- package/x/views/use.js.map +0 -1
- package/x/views/utils/apply-attrs.d.ts +0 -2
- package/x/views/utils/apply-attrs.js +0 -21
- package/x/views/utils/apply-attrs.js.map +0 -1
- package/x/views/utils/apply-styles.js.map +0 -1
- package/x/views/utils/attr-watcher.js.map +0 -1
- package/x/views/utils/mounts.js.map +0 -1
- package/x/views/utils/reactor.js.map +0 -1
- package/x/views/view.d.ts +0 -13
- package/x/views/view.js +0 -145
- package/x/views/view.js.map +0 -1
- /package/s/{views → base}/css-reset.ts +0 -0
- /package/s/{views → base}/utils/apply-styles.ts +0 -0
- /package/s/{views → base}/utils/attr-watcher.ts +0 -0
- /package/s/{views → base}/utils/mounts.ts +0 -0
- /package/x/{views → base}/css-reset.d.ts +0 -0
- /package/x/{views → base}/css-reset.js +0 -0
- /package/x/{views → base}/utils/apply-styles.d.ts +0 -0
- /package/x/{views → base}/utils/apply-styles.js +0 -0
- /package/x/{views → base}/utils/attr-watcher.d.ts +0 -0
- /package/x/{views → base}/utils/attr-watcher.js +0 -0
- /package/x/{views → base}/utils/mounts.d.ts +0 -0
- /package/x/{views → base}/utils/mounts.js +0 -0
- /package/x/{ops/loaders → loaders}/parts/anims.js +0 -0
- /package/x/{views → loaders}/types.js +0 -0
|
@@ -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,70 +1,32 @@
|
|
|
1
1
|
|
|
2
2
|
import {render} from "lit"
|
|
3
|
-
import {
|
|
3
|
+
import {el} from "./parts/el.js"
|
|
4
|
+
import {mk} from "./parts/mk.js"
|
|
5
|
+
import {eve} from "./parts/eve.js"
|
|
4
6
|
import {attrs} from "./attrs/attrs.js"
|
|
5
|
-
import {
|
|
7
|
+
import {elmer} from "./parts/elmer.js"
|
|
8
|
+
import {Content} from "../view/types.js"
|
|
9
|
+
import {Dom} from "./parts/dom-scope.js"
|
|
6
10
|
import {register} from "./parts/register.js"
|
|
11
|
+
import {Queryable, Renderable} from "./types.js"
|
|
12
|
+
import {queryAll, queryMaybe, queryRequire} from "./parts/queries.js"
|
|
7
13
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function require<E extends Element>(
|
|
12
|
-
container: Queryable,
|
|
13
|
-
selector: string,
|
|
14
|
-
) {
|
|
15
|
-
const e = container.querySelector<E>(selector)
|
|
16
|
-
if (!e) throw new Error(`element not found (${selector})`)
|
|
17
|
-
return e
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export class Dom<C extends Queryable> {
|
|
21
|
-
constructor(public element: C) {}
|
|
22
|
-
|
|
23
|
-
in<E extends HTMLElement>(selectorOrElement: string | E) {
|
|
24
|
-
return new Dom<E>(
|
|
25
|
-
(typeof selectorOrElement === "string")
|
|
26
|
-
? require(this.element, selectorOrElement) as E
|
|
27
|
-
: selectorOrElement
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
require<E extends Element = HTMLElement>(selector: string) {
|
|
32
|
-
const e = this.element.querySelector<E>(selector)
|
|
33
|
-
if (!e) throw new Error(`element not found (${selector})`)
|
|
34
|
-
return e
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
maybe<E extends Element = HTMLElement>(selector: string) {
|
|
38
|
-
return this.element.querySelector<E>(selector)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
all<E extends Element = HTMLElement>(selector: string) {
|
|
42
|
-
return Array.from(this.element.querySelectorAll<E>(selector))
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
render(...content: Content[]) {
|
|
46
|
-
return render(content, this.element as Renderable)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
attrs() {
|
|
50
|
-
return attrs(this.element as HTMLElement)
|
|
51
|
-
}
|
|
14
|
+
export function dom<E extends Element>(selector: string, container: Queryable = document): E {
|
|
15
|
+
return queryRequire<E>(selector, container)
|
|
52
16
|
}
|
|
53
17
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
export function dom<E extends Queryable>(selectorOrElement: string | E): E | Dom<E> {
|
|
57
|
-
return (typeof selectorOrElement === "string")
|
|
58
|
-
? require(document, selectorOrElement) as E
|
|
59
|
-
: new Dom(selectorOrElement)
|
|
18
|
+
dom.in = <E extends HTMLElement>(selectorOrElement: string | E, container: Queryable = document) => {
|
|
19
|
+
return new Dom(container).in(selectorOrElement)
|
|
60
20
|
}
|
|
61
21
|
|
|
62
|
-
|
|
63
|
-
dom.
|
|
64
|
-
dom.
|
|
65
|
-
dom.maybe = doc.maybe.bind(doc)
|
|
66
|
-
dom.all = doc.all.bind(doc)
|
|
22
|
+
dom.require = queryRequire
|
|
23
|
+
dom.maybe = queryMaybe
|
|
24
|
+
dom.all = queryAll
|
|
67
25
|
|
|
26
|
+
dom.el = el
|
|
27
|
+
dom.elmer = elmer
|
|
28
|
+
dom.mk = mk
|
|
29
|
+
dom.events = eve
|
|
68
30
|
dom.attrs = attrs
|
|
69
31
|
dom.register = register
|
|
70
32
|
dom.render = (container: Renderable, ...content: Content[]) => {
|
package/s/dom/index.ts
ADDED
|
@@ -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
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
import {AttrValue} from "../types.js"
|
|
3
|
+
import {attrSet} from "../attrs/parts/attr-fns.js"
|
|
4
|
+
|
|
5
|
+
export function el<E extends HTMLElement>(
|
|
6
|
+
tagName: string,
|
|
7
|
+
attrs: Record<string, AttrValue> = {},
|
|
8
|
+
) {
|
|
9
|
+
|
|
10
|
+
const element = document.createElement(tagName) as E
|
|
11
|
+
attrSet.record(element, attrs)
|
|
12
|
+
return element
|
|
13
|
+
}
|
|
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
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
export type EveFn = (event: any) => void
|
|
3
|
+
export type EveConfig = [options: AddEventListenerOptions, fn: EveFn]
|
|
4
|
+
export type EveHandler = EveFn | EveConfig
|
|
5
|
+
export type EveSpec = {[eventName: string]: EveHandler}
|
|
6
|
+
|
|
7
|
+
export function eve(target: EventTarget, events: EveSpec) {
|
|
8
|
+
let detachers: (() => void)[] = []
|
|
9
|
+
|
|
10
|
+
for (const [eventName, handler] of Object.entries(events)) {
|
|
11
|
+
if (typeof handler === "function") {
|
|
12
|
+
target.addEventListener(eventName, handler)
|
|
13
|
+
detachers.push(() => target.removeEventListener(eventName, handler))
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
const [options, fn] = handler
|
|
17
|
+
target.addEventListener(eventName, fn, options)
|
|
18
|
+
detachers.push(() => target.removeEventListener(eventName, fn))
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return () => detachers.forEach(d => d())
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
import {Queryable} from "../types.js"
|
|
3
|
+
|
|
4
|
+
export function queryRequire<E extends Element>(
|
|
5
|
+
selector: string,
|
|
6
|
+
container: Queryable = document,
|
|
7
|
+
) {
|
|
8
|
+
const e = container.querySelector<E>(selector)
|
|
9
|
+
if (!e) throw new Error(`element not found (${selector})`)
|
|
10
|
+
return e
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function queryMaybe<E extends Element>(
|
|
14
|
+
selector: string,
|
|
15
|
+
container: Queryable = document,
|
|
16
|
+
) {
|
|
17
|
+
return container.querySelector<E>(selector)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function queryAll<E extends Element>(
|
|
21
|
+
selector: string,
|
|
22
|
+
container: Queryable = document,
|
|
23
|
+
) {
|
|
24
|
+
return Array.from(container.querySelectorAll<E>(selector))
|
|
25
|
+
}
|
|
26
|
+
|
package/s/dom/types.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
|
|
2
2
|
import {attrs} from "./attrs/attrs.js"
|
|
3
3
|
|
|
4
|
+
export type Renderable = HTMLElement | ShadowRoot | DocumentFragment
|
|
5
|
+
export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment
|
|
6
|
+
|
|
4
7
|
// attrs
|
|
5
8
|
|
|
9
|
+
export type AttrValue = string | boolean | number | undefined | null | void
|
|
10
|
+
|
|
6
11
|
export type AttrKind = (
|
|
7
12
|
| typeof String
|
|
8
13
|
| typeof Number
|
package/s/index.html.ts
CHANGED
|
@@ -29,10 +29,10 @@ export default ssg.page(import.meta.url, async orb => ({
|
|
|
29
29
|
<h1>sly testing page</h1>
|
|
30
30
|
<p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
|
|
31
31
|
<p class=lil>v${orb.packageVersion()}</p>
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
<
|
|
32
|
+
|
|
33
|
+
<fastcount-element></fastcount-element>
|
|
34
|
+
<counter-component start=280 step=2>component</counter-component>
|
|
35
|
+
<demo-component></demo-component>
|
|
36
36
|
`,
|
|
37
37
|
}))
|
|
38
38
|
|
package/s/index.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./dom/
|
|
4
|
-
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./ops/
|
|
7
|
-
export * from "./
|
|
8
|
-
export * from "./
|
|
9
|
-
export * from "./ops/podium.js"
|
|
10
|
-
export * from "./ops/types.js"
|
|
11
|
-
|
|
12
|
-
export * as loot from "./loot/index.js"
|
|
13
|
-
|
|
14
|
-
export * from "./views/base-element.js"
|
|
15
|
-
export * from "./views/css-reset.js"
|
|
16
|
-
export * from "./views/types.js"
|
|
17
|
-
export * from "./views/use.js"
|
|
18
|
-
export * from "./views/view.js"
|
|
2
|
+
export * from "./base/index.js"
|
|
3
|
+
export * from "./dom/index.js"
|
|
4
|
+
export * from "./loaders/index.js"
|
|
5
|
+
export * from "./loot/index.js"
|
|
6
|
+
export * from "./ops/index.js"
|
|
7
|
+
export * from "./spa/index.js"
|
|
8
|
+
export * from "./view/index.js"
|
|
19
9
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
import {Loader} from "./types.js"
|
|
3
|
+
import {earth} from "./parts/anims.js"
|
|
4
|
+
import type {Content} from "../view/types.js"
|
|
5
|
+
import {ErrorDisplay} from "./parts/error-display.js"
|
|
6
|
+
|
|
7
|
+
export function make(
|
|
8
|
+
loading: () => Content = earth,
|
|
9
|
+
error: (error: any) => Content = (error: any) => ErrorDisplay(error),
|
|
10
|
+
): Loader {
|
|
11
|
+
|
|
12
|
+
return (op, ready) => op.select({loading, ready, error})
|
|
13
|
+
}
|
|
14
|
+
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
import {css} from "lit"
|
|
3
|
-
import {nap,
|
|
3
|
+
import {nap, cycle} from "@e280/stz"
|
|
4
4
|
|
|
5
|
-
import {view} from "
|
|
6
|
-
import {Content} from "
|
|
7
|
-
import {cssReset} from "
|
|
5
|
+
import {view} from "../../view/view.js"
|
|
6
|
+
import {Content} from "../../view/types.js"
|
|
7
|
+
import {cssReset} from "../../base/css-reset.js"
|
|
8
8
|
|
|
9
9
|
export function makeAsciiAnim(hz: number, frames: string[]): () => Content {
|
|
10
10
|
return () => AsciiAnim({hz, frames})
|
|
@@ -17,9 +17,10 @@ export const AsciiAnim = view(use => ({hz, frames}: {
|
|
|
17
17
|
|
|
18
18
|
use.name("loading")
|
|
19
19
|
use.styles(cssReset, style)
|
|
20
|
+
|
|
20
21
|
const frame = use.signal(0)
|
|
21
22
|
|
|
22
|
-
use.mount(() =>
|
|
23
|
+
use.mount(() => cycle(async() => {
|
|
23
24
|
await nap(1000 / hz)
|
|
24
25
|
const next = frame.get() + 1
|
|
25
26
|
frame.set(next >= frames.length ? 0 : next)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import {css, html} from "lit"
|
|
3
|
-
import {view} from "
|
|
4
|
-
import {cssReset} from "
|
|
3
|
+
import {view} from "../../view/view.js"
|
|
4
|
+
import {cssReset} from "../../base/css-reset.js"
|
|
5
5
|
|
|
6
6
|
export const ErrorDisplay = view(use => (error: any) => {
|
|
7
7
|
use.name("error")
|
package/s/loot/index.ts
CHANGED
package/s/ops/index.ts
ADDED
package/s/ops/op.ts
CHANGED
package/s/spa/index.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
|
|
2
|
+
import {Hasher, Route} from "./types.js"
|
|
3
|
+
import type {Content} from "../../view/types.js"
|
|
4
|
+
|
|
5
|
+
type ParamKeys<S extends string> =
|
|
6
|
+
S extends `${string}{${infer P}}${infer R}` ? (string & P) | ParamKeys<R> : never
|
|
7
|
+
|
|
8
|
+
type ParamsOf<S extends string> =
|
|
9
|
+
[ParamKeys<S>] extends [never] ? {} : { [K in ParamKeys<S>]: string }
|
|
10
|
+
|
|
11
|
+
type ParamsTuple<S extends string> =
|
|
12
|
+
keyof ParamsOf<S> extends never ? [] : [ParamsOf<S>]
|
|
13
|
+
|
|
14
|
+
export function hasher<S extends string>(spec: S): Hasher<ParamsTuple<S>> {
|
|
15
|
+
if (!spec.startsWith("#/"))
|
|
16
|
+
throw new Error(`hash route spec must start with "#/"`)
|
|
17
|
+
|
|
18
|
+
const specparts = spec.split("/")
|
|
19
|
+
const braceregex = /\{([^\}\/]+)\}/
|
|
20
|
+
|
|
21
|
+
function parse(hash: string): ParamsTuple<S> | null {
|
|
22
|
+
if (!hash.startsWith("#/"))
|
|
23
|
+
throw new Error(`hash must start with "#/"`)
|
|
24
|
+
|
|
25
|
+
const hashparts = hash.split("/")
|
|
26
|
+
const params: Record<string, string> = {}
|
|
27
|
+
|
|
28
|
+
if (hashparts.length !== specparts.length)
|
|
29
|
+
return null
|
|
30
|
+
|
|
31
|
+
for (const [index, specpart] of specparts.entries()) {
|
|
32
|
+
const hashpart = hashparts.at(index)
|
|
33
|
+
if (hashpart === undefined) return null
|
|
34
|
+
const bracematch = specpart.match(braceregex)
|
|
35
|
+
try {
|
|
36
|
+
if (bracematch) params[bracematch[1]] = decodeURIComponent(hashpart)
|
|
37
|
+
else if (hashpart !== specpart) return null
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (Object.keys(params).length === 0)
|
|
45
|
+
? ([] as ParamsTuple<S>)
|
|
46
|
+
: ([params as ParamsOf<S>] as ParamsTuple<S>)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function make(...[braces]: any[]): string {
|
|
50
|
+
const get = (param: string) => {
|
|
51
|
+
const p = param as any
|
|
52
|
+
if (p in braces) return braces[p]
|
|
53
|
+
else throw new Error(`missing param "${p}"`)
|
|
54
|
+
}
|
|
55
|
+
return specparts.map(specpart => {
|
|
56
|
+
const bracematch = specpart.match(braceregex)
|
|
57
|
+
return bracematch
|
|
58
|
+
? encodeURIComponent(get(bracematch[1]))
|
|
59
|
+
: specpart
|
|
60
|
+
}).join("/")
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {parse, make}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function route<S extends string>(
|
|
67
|
+
spec: S,
|
|
68
|
+
fn: (...params: ParamsTuple<S>) => Promise<Content>,
|
|
69
|
+
): Route<ParamsTuple<S>> {
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
hasher: hasher(spec),
|
|
73
|
+
fn,
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
|
|
2
|
+
import {ev, ob} from "@e280/stz"
|
|
3
|
+
import {Op} from "../../ops/op.js"
|
|
4
|
+
import {ResolvedRoute, Route, Params, Routes} from "./types.js"
|
|
5
|
+
|
|
6
|
+
export function eraseWindowHash() {
|
|
7
|
+
const {pathname, search} = window.location
|
|
8
|
+
history.replaceState(null, "", pathname + search)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function normalizeHash(hash: string) {
|
|
12
|
+
const homeEquivalents = [/^$/, /^#$/, /^#\/$/]
|
|
13
|
+
return (homeEquivalents.some(regex => regex.test(hash)))
|
|
14
|
+
? "#/"
|
|
15
|
+
: hash
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class HashNormalizer {
|
|
19
|
+
constructor(public location: Location) {}
|
|
20
|
+
|
|
21
|
+
get hash() {
|
|
22
|
+
const hash = normalizeHash(this.location.hash)
|
|
23
|
+
if (hash === "#/") eraseWindowHash()
|
|
24
|
+
return hash
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
set hash(hash: string) {
|
|
28
|
+
this.location.hash = hash
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class Navigable<P extends any[] = any[]> {
|
|
33
|
+
static all<R extends Routes>(
|
|
34
|
+
routes: R,
|
|
35
|
+
getRoute: () => Route | null,
|
|
36
|
+
navigate: (hash: string) => Promise<ResolvedRoute>,
|
|
37
|
+
): {[K in keyof R]: Navigable<Params<R[K]>>} {
|
|
38
|
+
|
|
39
|
+
return ob(routes).map(route => new this(
|
|
40
|
+
route,
|
|
41
|
+
() => (getRoute() === route),
|
|
42
|
+
async(...params: any[]) => navigate(route.hasher.make(...params)),
|
|
43
|
+
)) as any
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
public route: Route<P>,
|
|
48
|
+
private isActive: () => boolean,
|
|
49
|
+
public go: (...params: P) => Promise<ResolvedRoute<P>>,
|
|
50
|
+
) {}
|
|
51
|
+
|
|
52
|
+
get active() {
|
|
53
|
+
return this.isActive()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
hash(...params: P) {
|
|
57
|
+
return this.route.hasher.make(...params)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function resolveRoute<R extends Routes>(
|
|
62
|
+
hash: string,
|
|
63
|
+
routes: R,
|
|
64
|
+
): ResolvedRoute | null {
|
|
65
|
+
|
|
66
|
+
for (const key in routes) {
|
|
67
|
+
const route = routes[key]
|
|
68
|
+
const params = route.hasher.parse(hash)
|
|
69
|
+
if (params) {
|
|
70
|
+
return {
|
|
71
|
+
key,
|
|
72
|
+
route,
|
|
73
|
+
params,
|
|
74
|
+
op: Op.promise(route.fn(...params))
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function onHashChange(fn: (event: HashChangeEvent) => void) {
|
|
83
|
+
return ev(window, {hashchange: fn})
|
|
84
|
+
}
|
|
85
|
+
|