@e280/sly 0.2.4 → 0.3.0-1
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/LICENSE +1 -1
- package/README.md +302 -614
- package/package.json +6 -8
- package/s/_archive/README.md +1221 -0
- package/s/{base → _archive/base}/element.ts +5 -2
- package/s/_archive/view/index.ts +7 -0
- package/s/_archive/view/types.ts +45 -0
- package/s/{view → _archive/view}/utils/parts/capsule.ts +9 -2
- package/s/demo/demo.bundle.ts +2 -9
- package/s/demo/views/counter-light.ts +13 -0
- package/s/demo/views/counter-shadow.ts +16 -0
- package/s/demo/views/demo.ts +24 -18
- package/s/demo/views/loaders.ts +7 -7
- package/s/index.html.ts +30 -33
- package/s/index.ts +0 -2
- package/s/loaders/make.ts +1 -1
- package/s/loaders/parts/ascii-anim.ts +6 -8
- package/s/loaders/parts/error-display.ts +9 -9
- package/s/tests.test.ts +1 -4
- package/s/view/common/css-reset.ts +19 -0
- package/s/view/hooks/plumbing/hooks.ts +28 -0
- package/s/view/hooks/plumbing/hookscope.ts +12 -0
- package/s/view/hooks/use-css.ts +14 -0
- package/s/view/hooks/use-cx.ts +41 -0
- package/s/view/hooks/use-life.ts +17 -0
- package/s/view/hooks/use-mount.ts +30 -0
- package/s/view/hooks/use-name.ts +10 -0
- package/s/view/hooks/use-once.ts +9 -0
- package/s/view/hooks/use-op.ts +12 -0
- package/s/view/hooks/use-ref.ts +11 -0
- package/s/view/hooks/use-signal.ts +16 -0
- package/s/view/hooks/use-state.ts +20 -0
- package/s/view/hooks/use-wake.ts +8 -0
- package/s/view/index.ts +17 -4
- package/s/view/light.ts +50 -0
- package/s/view/parts/apply-attrs.ts +22 -0
- package/s/view/parts/apply-styles.ts +21 -0
- package/s/view/parts/cx.ts +26 -0
- package/s/view/parts/reactivity.ts +22 -0
- package/s/view/parts/sly-shadow.ts +8 -0
- package/s/view/shadow.ts +93 -0
- package/s/view/types.ts +15 -34
- package/x/demo/demo.bundle.js +2 -8
- package/x/demo/demo.bundle.js.map +1 -1
- package/x/demo/demo.bundle.min.js +45 -58
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/demo/views/counter-light.d.ts +1 -0
- package/x/demo/views/counter-light.js +10 -0
- package/x/demo/views/counter-light.js.map +1 -0
- package/x/demo/views/counter-shadow.d.ts +1 -0
- package/x/demo/views/counter-shadow.js +12 -0
- package/x/demo/views/counter-shadow.js.map +1 -0
- package/x/demo/views/demo.d.ts +1 -4
- package/x/demo/views/demo.js +23 -18
- package/x/demo/views/demo.js.map +1 -1
- package/x/demo/views/loaders.d.ts +1 -1
- package/x/demo/views/loaders.js +7 -7
- package/x/demo/views/loaders.js.map +1 -1
- package/x/index.d.ts +0 -2
- package/x/index.html +30 -140
- package/x/index.html.js +31 -31
- package/x/index.html.js.map +1 -1
- package/x/index.js +0 -2
- package/x/index.js.map +1 -1
- package/x/loaders/make.d.ts +1 -1
- package/x/loaders/parts/ascii-anim.d.ts +1 -1
- package/x/loaders/parts/ascii-anim.js +6 -7
- package/x/loaders/parts/ascii-anim.js.map +1 -1
- package/x/loaders/parts/error-display.d.ts +1 -1
- package/x/loaders/parts/error-display.js +9 -9
- package/x/loaders/parts/error-display.js.map +1 -1
- package/x/tests.test.js +1 -4
- package/x/tests.test.js.map +1 -1
- package/x/view/common/css-reset.js +17 -0
- package/x/view/common/css-reset.js.map +1 -0
- package/x/view/hooks/plumbing/hooks.d.ts +11 -0
- package/x/view/hooks/plumbing/hooks.js +26 -0
- package/x/view/hooks/plumbing/hooks.js.map +1 -0
- package/x/view/hooks/plumbing/hookscope.d.ts +10 -0
- package/x/view/hooks/plumbing/hookscope.js +12 -0
- package/x/view/hooks/plumbing/hookscope.js.map +1 -0
- package/x/view/hooks/use-css.d.ts +4 -0
- package/x/view/hooks/use-css.js +10 -0
- package/x/view/hooks/use-css.js.map +1 -0
- package/x/view/hooks/use-cx.d.ts +10 -0
- package/x/view/hooks/use-cx.js +33 -0
- package/x/view/hooks/use-cx.js.map +1 -0
- package/x/view/hooks/use-life.d.ts +2 -0
- package/x/view/hooks/use-life.js +13 -0
- package/x/view/hooks/use-life.js.map +1 -0
- package/x/{base/utils/mounts.d.ts → view/hooks/use-mount.d.ts} +1 -0
- package/x/{base/utils/mounts.js → view/hooks/use-mount.js} +7 -1
- package/x/view/hooks/use-mount.js.map +1 -0
- package/x/view/hooks/use-name.d.ts +2 -0
- package/x/view/hooks/use-name.js +8 -0
- package/x/view/hooks/use-name.js.map +1 -0
- package/x/view/hooks/use-once.d.ts +2 -0
- package/x/view/hooks/use-once.js +7 -0
- package/x/view/hooks/use-once.js.map +1 -0
- package/x/view/hooks/use-op.d.ts +3 -0
- package/x/view/hooks/use-op.js +9 -0
- package/x/view/hooks/use-op.js.map +1 -0
- package/x/view/hooks/use-ref.d.ts +5 -0
- package/x/view/hooks/use-ref.js +11 -0
- package/x/view/hooks/use-ref.js.map +1 -0
- package/x/view/hooks/use-signal.d.ts +3 -0
- package/x/view/hooks/use-signal.js +12 -0
- package/x/view/hooks/use-signal.js.map +1 -0
- package/x/view/hooks/use-state.d.ts +1 -0
- package/x/view/hooks/use-state.js +17 -0
- package/x/view/hooks/use-state.js.map +1 -0
- package/x/view/hooks/use-wake.d.ts +2 -0
- package/x/view/hooks/use-wake.js +6 -0
- package/x/view/hooks/use-wake.js.map +1 -0
- package/x/view/index.d.ts +15 -4
- package/x/view/index.js +15 -4
- package/x/view/index.js.map +1 -1
- package/x/view/light.d.ts +2 -0
- package/x/view/light.js +41 -0
- package/x/view/light.js.map +1 -0
- package/x/view/parts/apply-attrs.d.ts +2 -0
- package/x/view/parts/apply-attrs.js +22 -0
- package/x/view/parts/apply-attrs.js.map +1 -0
- package/x/{base/utils → view/parts}/apply-styles.js.map +1 -1
- package/x/view/parts/cx.d.ts +12 -0
- package/x/view/parts/cx.js +24 -0
- package/x/view/parts/cx.js.map +1 -0
- package/x/view/parts/reactivity.d.ts +5 -0
- package/x/view/parts/reactivity.js +18 -0
- package/x/view/parts/reactivity.js.map +1 -0
- package/x/view/parts/sly-shadow.d.ts +3 -0
- package/x/view/parts/sly-shadow.js +7 -0
- package/x/view/parts/sly-shadow.js.map +1 -0
- package/x/view/shadow.d.ts +6 -0
- package/x/view/shadow.js +72 -0
- package/x/view/shadow.js.map +1 -0
- package/x/view/types.d.ts +13 -21
- package/s/demo/views/counter.ts +0 -50
- package/s/demo/views/fastcount.ts +0 -29
- package/x/base/css-reset.js +0 -19
- package/x/base/css-reset.js.map +0 -1
- package/x/base/element.d.ts +0 -19
- package/x/base/element.js +0 -52
- package/x/base/element.js.map +0 -1
- package/x/base/index.d.ts +0 -5
- package/x/base/index.js +0 -6
- package/x/base/index.js.map +0 -1
- package/x/base/types.d.ts +0 -3
- package/x/base/types.js +0 -3
- package/x/base/types.js.map +0 -1
- package/x/base/use.d.ts +0 -59
- package/x/base/use.js +0 -129
- package/x/base/use.js.map +0 -1
- package/x/base/utils/attr-watcher.d.ts +0 -8
- package/x/base/utils/attr-watcher.js +0 -20
- package/x/base/utils/attr-watcher.js.map +0 -1
- package/x/base/utils/mounts.js.map +0 -1
- package/x/base/utils/reactor.d.ts +0 -5
- package/x/base/utils/reactor.js +0 -25
- package/x/base/utils/reactor.js.map +0 -1
- package/x/base/utils/states.d.ts +0 -13
- package/x/base/utils/states.js +0 -41
- package/x/base/utils/states.js.map +0 -1
- package/x/base/utils/use-attrs.d.ts +0 -11
- package/x/base/utils/use-attrs.js +0 -18
- package/x/base/utils/use-attrs.js.map +0 -1
- package/x/demo/views/counter.d.ts +0 -374
- package/x/demo/views/counter.js +0 -42
- package/x/demo/views/counter.js.map +0 -1
- package/x/demo/views/fastcount.d.ts +0 -12
- package/x/demo/views/fastcount.js +0 -21
- package/x/demo/views/fastcount.js.map +0 -1
- package/x/spa/index.barrel.d.ts +0 -4
- package/x/spa/index.barrel.js +0 -3
- package/x/spa/index.barrel.js.map +0 -1
- package/x/spa/index.d.ts +0 -2
- package/x/spa/index.js +0 -2
- package/x/spa/index.js.map +0 -1
- package/x/spa/plumbing/braces.d.ts +0 -12
- package/x/spa/plumbing/braces.js +0 -55
- package/x/spa/plumbing/braces.js.map +0 -1
- package/x/spa/plumbing/primitives.d.ts +0 -22
- package/x/spa/plumbing/primitives.js +0 -65
- package/x/spa/plumbing/primitives.js.map +0 -1
- package/x/spa/plumbing/router-core.d.ts +0 -13
- package/x/spa/plumbing/router-core.js +0 -38
- package/x/spa/plumbing/router-core.js.map +0 -1
- package/x/spa/plumbing/types.d.ts +0 -35
- package/x/spa/plumbing/types.js +0 -2
- package/x/spa/plumbing/types.js.map +0 -1
- package/x/spa/router.d.ts +0 -13
- package/x/spa/router.js +0 -39
- package/x/spa/router.js.map +0 -1
- package/x/spa/spa.test.d.ts +0 -15
- package/x/spa/spa.test.js +0 -78
- package/x/spa/spa.test.js.map +0 -1
- package/x/view/utils/contextualize.d.ts +0 -13
- package/x/view/utils/contextualize.js +0 -18
- package/x/view/utils/contextualize.js.map +0 -1
- package/x/view/utils/make-component.d.ts +0 -5
- package/x/view/utils/make-component.js +0 -17
- package/x/view/utils/make-component.js.map +0 -1
- package/x/view/utils/make-view.d.ts +0 -2
- package/x/view/utils/make-view.js +0 -32
- package/x/view/utils/make-view.js.map +0 -1
- package/x/view/utils/parts/capsule.d.ts +0 -12
- package/x/view/utils/parts/capsule.js +0 -50
- package/x/view/utils/parts/capsule.js.map +0 -1
- package/x/view/utils/parts/chain.d.ts +0 -13
- package/x/view/utils/parts/chain.js +0 -26
- package/x/view/utils/parts/chain.js.map +0 -1
- package/x/view/utils/parts/context.d.ts +0 -9
- package/x/view/utils/parts/context.js +0 -10
- package/x/view/utils/parts/context.js.map +0 -1
- package/x/view/utils/parts/directive.d.ts +0 -5
- package/x/view/utils/parts/directive.js +0 -20
- package/x/view/utils/parts/directive.js.map +0 -1
- package/x/view/utils/parts/naked.d.ts +0 -18
- package/x/view/utils/parts/naked.js +0 -57
- package/x/view/utils/parts/naked.js.map +0 -1
- package/x/view/utils/parts/sly-view.d.ts +0 -6
- package/x/view/utils/parts/sly-view.js +0 -16
- package/x/view/utils/parts/sly-view.js.map +0 -1
- package/x/view/view.d.ts +0 -11
- package/x/view/view.js +0 -15
- package/x/view/view.js.map +0 -1
- /package/s/{base → _archive/base}/css-reset.ts +0 -0
- /package/s/{base → _archive/base}/index.ts +0 -0
- /package/s/{base → _archive/base}/types.ts +0 -0
- /package/s/{base → _archive/base}/use.ts +0 -0
- /package/s/{base → _archive/base}/utils/apply-styles.ts +0 -0
- /package/s/{base → _archive/base}/utils/attr-watcher.ts +0 -0
- /package/s/{base → _archive/base}/utils/mounts.ts +0 -0
- /package/s/{base → _archive/base}/utils/reactor.ts +0 -0
- /package/s/{base → _archive/base}/utils/states.ts +0 -0
- /package/s/{base → _archive/base}/utils/use-attrs.ts +0 -0
- /package/s/{spa → _archive/spa}/index.barrel.ts +0 -0
- /package/s/{spa → _archive/spa}/index.ts +0 -0
- /package/s/{spa → _archive/spa}/plumbing/braces.ts +0 -0
- /package/s/{spa → _archive/spa}/plumbing/primitives.ts +0 -0
- /package/s/{spa → _archive/spa}/plumbing/router-core.ts +0 -0
- /package/s/{spa → _archive/spa}/plumbing/types.ts +0 -0
- /package/s/{spa → _archive/spa}/router.ts +0 -0
- /package/s/{spa → _archive/spa}/spa.test.ts +0 -0
- /package/s/{view → _archive/view}/utils/contextualize.ts +0 -0
- /package/s/{view → _archive/view}/utils/make-component.ts +0 -0
- /package/s/{view → _archive/view}/utils/make-view.ts +0 -0
- /package/s/{view → _archive/view}/utils/parts/chain.ts +0 -0
- /package/s/{view → _archive/view}/utils/parts/context.ts +0 -0
- /package/s/{view → _archive/view}/utils/parts/directive.ts +0 -0
- /package/s/{view → _archive/view}/utils/parts/naked.ts +0 -0
- /package/s/{view → _archive/view}/utils/parts/sly-view.ts +0 -0
- /package/s/{view → _archive/view}/view.ts +0 -0
- /package/x/{base → view/common}/css-reset.d.ts +0 -0
- /package/x/{base/utils → view/parts}/apply-styles.d.ts +0 -0
- /package/x/{base/utils → view/parts}/apply-styles.js +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import {debounce} from "@e280/stz"
|
|
3
|
+
import type {RootPart} from "lit-html"
|
|
3
4
|
import {CSSResultGroup} from "lit"
|
|
4
5
|
|
|
5
6
|
import {dom} from "../dom/dom.js"
|
|
@@ -18,6 +19,7 @@ export class BaseElement extends HTMLElement {
|
|
|
18
19
|
#mountCount = 0
|
|
19
20
|
#reactor = new Reactor()
|
|
20
21
|
#attrWatcher = new AttrWatcher(this, () => this.update())
|
|
22
|
+
#part?: RootPart
|
|
21
23
|
|
|
22
24
|
/** create the shadow root. override this if you want to change the shadow root settings. */
|
|
23
25
|
createShadow() {
|
|
@@ -41,7 +43,7 @@ export class BaseElement extends HTMLElement {
|
|
|
41
43
|
/** immediately perform a fresh render into the shadow root. */
|
|
42
44
|
updateNow = () => {
|
|
43
45
|
this.#use[_wrap](() => {
|
|
44
|
-
dom.render(
|
|
46
|
+
this.#part = dom.render(
|
|
45
47
|
this.shadow,
|
|
46
48
|
this.#reactor.effect(
|
|
47
49
|
() => this.render(this.#use),
|
|
@@ -62,15 +64,16 @@ export class BaseElement extends HTMLElement {
|
|
|
62
64
|
}
|
|
63
65
|
else {
|
|
64
66
|
this.#use[_reconnect]()
|
|
67
|
+
this.#part?.setConnected(true)
|
|
65
68
|
}
|
|
66
69
|
this.#attrWatcher.start()
|
|
67
70
|
this.#mountCount++
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
disconnectedCallback() {
|
|
74
|
+
this.#part?.setConnected(false)
|
|
71
75
|
this.#use[_disconnect]()
|
|
72
76
|
this.#reactor.clear()
|
|
73
77
|
this.#attrWatcher.stop()
|
|
74
78
|
}
|
|
75
79
|
}
|
|
76
|
-
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
|
|
2
|
+
import {TemplateResult} from "lit"
|
|
3
|
+
import {Constructor} from "@e280/stz"
|
|
4
|
+
import {DirectiveResult} from "lit/directive.js"
|
|
5
|
+
|
|
6
|
+
import {Use} from "../base/use.js"
|
|
7
|
+
import {BaseElement} from "../base/element.js"
|
|
8
|
+
import {ViewChain} from "./utils/parts/chain.js"
|
|
9
|
+
|
|
10
|
+
export type Content = TemplateResult | DirectiveResult | HTMLElement | string | null | undefined | void | Content[]
|
|
11
|
+
|
|
12
|
+
export type ViewFn<Props extends any[]> = (
|
|
13
|
+
(use: Use) =>
|
|
14
|
+
(...props: Props) =>
|
|
15
|
+
Content
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
export type View<Props extends any[]> = {
|
|
19
|
+
(...props: Props): DirectiveResult
|
|
20
|
+
props: (...props: Props) => ViewChain<Props>
|
|
21
|
+
transmute: <PropsB extends any[]>(convert: (...propsB: PropsB) => Props) => View<PropsB>
|
|
22
|
+
component: <B extends Constructor<BaseElement>>(Base?: B) => {
|
|
23
|
+
props: (propFn: (component: InstanceType<B>) => Props) => (
|
|
24
|
+
ComponentClass<B, Props>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
naked: (host: HTMLElement) => NakedView<Props>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type ViewProps<V extends View<any>> = (
|
|
31
|
+
V extends View<infer Props>
|
|
32
|
+
? Props
|
|
33
|
+
: never
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
export type ComponentClass<B extends Constructor<BaseElement>, Props extends any[]> = {
|
|
37
|
+
view: View<Props>
|
|
38
|
+
new(): InstanceType<B>
|
|
39
|
+
} & B
|
|
40
|
+
|
|
41
|
+
export type NakedView<Props extends any[]> = {
|
|
42
|
+
host: HTMLElement
|
|
43
|
+
render: (...props: Props) => void
|
|
44
|
+
}
|
|
45
|
+
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
import {RootPart} from "lit"
|
|
2
3
|
import {debounce} from "@e280/stz"
|
|
3
4
|
import {ViewFn} from "../../types.js"
|
|
4
5
|
import {dom} from "../../../dom/dom.js"
|
|
@@ -17,6 +18,8 @@ export class ViewCapsule<Props extends any[]> {
|
|
|
17
18
|
#shadow: ShadowRoot
|
|
18
19
|
#context!: ViewContext<Props>
|
|
19
20
|
#attrWatcher: AttrWatcher
|
|
21
|
+
#partShadow?: RootPart
|
|
22
|
+
#partElement?: RootPart
|
|
20
23
|
|
|
21
24
|
constructor(
|
|
22
25
|
host: HTMLElement,
|
|
@@ -47,8 +50,8 @@ export class ViewCapsule<Props extends any[]> {
|
|
|
47
50
|
() => this.#renderDebounced(),
|
|
48
51
|
)
|
|
49
52
|
attrSet.entries(this.#element, this.#context.attrs)
|
|
50
|
-
dom.render(this.#shadow, content)
|
|
51
|
-
dom.render(this.#element, this.#context.children)
|
|
53
|
+
this.#partShadow = dom.render(this.#shadow, content)
|
|
54
|
+
this.#partElement = dom.render(this.#element, this.#context.children)
|
|
52
55
|
this.#attrWatcher.start()
|
|
53
56
|
})
|
|
54
57
|
}
|
|
@@ -56,6 +59,8 @@ export class ViewCapsule<Props extends any[]> {
|
|
|
56
59
|
#renderDebounced = debounce(0, this.#renderNow)
|
|
57
60
|
|
|
58
61
|
disconnected() {
|
|
62
|
+
this.#partShadow?.setConnected(false)
|
|
63
|
+
this.#partElement?.setConnected(false)
|
|
59
64
|
this.#use[_disconnect]()
|
|
60
65
|
this.#reactor.clear()
|
|
61
66
|
this.#attrWatcher.stop()
|
|
@@ -64,6 +69,8 @@ export class ViewCapsule<Props extends any[]> {
|
|
|
64
69
|
reconnected() {
|
|
65
70
|
this.#use[_reconnect]()
|
|
66
71
|
this.#attrWatcher.start()
|
|
72
|
+
this.#partShadow?.setConnected(true)
|
|
73
|
+
this.#partElement?.setConnected(true)
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
|
package/s/demo/demo.bundle.ts
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import {dom} from "../dom/dom.js"
|
|
3
|
-
import {
|
|
4
|
-
import {DemoComponent} from "./views/demo.js"
|
|
5
|
-
import {FastcountElement} from "./views/fastcount.js"
|
|
6
|
-
|
|
7
|
-
dom.register({
|
|
8
|
-
DemoComponent,
|
|
9
|
-
CounterComponent,
|
|
10
|
-
FastcountElement,
|
|
11
|
-
})
|
|
3
|
+
import {Demo} from "./views/demo.js"
|
|
12
4
|
|
|
5
|
+
dom.in(".demo").render(Demo())
|
|
13
6
|
console.log("🦝 sly")
|
|
14
7
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
import {html} from "lit"
|
|
3
|
+
import {light, useSignal} from "../../view/index.js"
|
|
4
|
+
|
|
5
|
+
export const CounterLight = light((start: number) => {
|
|
6
|
+
const $count = useSignal(start)
|
|
7
|
+
const increment = () => $count.value++
|
|
8
|
+
|
|
9
|
+
return html`
|
|
10
|
+
<button @click="${increment}">${$count()}</button>
|
|
11
|
+
`
|
|
12
|
+
})
|
|
13
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
import {css, html} from "lit"
|
|
3
|
+
import {shadow, useName, useCss, useSignal} from "../../view/index.js"
|
|
4
|
+
|
|
5
|
+
export const CounterShadow = shadow((start: number) => {
|
|
6
|
+
useName("counter-shadow")
|
|
7
|
+
useCss(css`:host{display:inline-block} button{color:cyan}`)
|
|
8
|
+
|
|
9
|
+
const $count = useSignal(start)
|
|
10
|
+
const increment = () => $count.value++
|
|
11
|
+
|
|
12
|
+
return html`
|
|
13
|
+
<button @click="${increment}">${$count()}</button>
|
|
14
|
+
`
|
|
15
|
+
})
|
|
16
|
+
|
package/s/demo/views/demo.ts
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
|
|
2
2
|
import {css, html} from "lit"
|
|
3
|
-
|
|
4
|
-
import {view} from "../../view/view.js"
|
|
5
|
-
import {CounterView} from "./counter.js"
|
|
6
3
|
import {LoadersView} from "./loaders.js"
|
|
7
|
-
import {
|
|
4
|
+
import {CounterLight} from "./counter-light.js"
|
|
5
|
+
import {CounterShadow} from "./counter-shadow.js"
|
|
6
|
+
import {cssReset, shadow, useName, useStyles} from "../../view/index.js"
|
|
7
|
+
|
|
8
|
+
export const Demo = shadow(() => {
|
|
9
|
+
useName("demo")
|
|
10
|
+
useStyles(cssReset, styles)
|
|
8
11
|
|
|
9
|
-
export class DemoComponent extends (view.component(use => {
|
|
10
|
-
use.name("demo")
|
|
11
|
-
use.styles(cssReset, styles)
|
|
12
12
|
return html`
|
|
13
|
-
${
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.
|
|
13
|
+
<p>light ${CounterLight(123)}</p>
|
|
14
|
+
|
|
15
|
+
<p>
|
|
16
|
+
shadow ${CounterShadow.with({
|
|
17
|
+
props: [234],
|
|
18
|
+
attrs: {"data-lol": 555},
|
|
19
|
+
children: html`<p>hello</p>`,
|
|
20
|
+
})}
|
|
21
|
+
</p>
|
|
22
|
+
|
|
17
23
|
${LoadersView()}
|
|
18
24
|
`
|
|
19
|
-
})
|
|
25
|
+
})
|
|
20
26
|
|
|
21
27
|
const styles = css`
|
|
22
|
-
:host {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
+
:host {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
align-items: center;
|
|
32
|
+
gap: 1em;
|
|
33
|
+
}
|
|
28
34
|
`
|
|
29
35
|
|
package/s/demo/views/loaders.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
import {css, html} from "lit"
|
|
3
3
|
import {Op} from "../../ops/op.js"
|
|
4
|
-
import {
|
|
4
|
+
import {shadow} from "../../view/shadow.js"
|
|
5
5
|
import {loaders} from "../../loaders/index.js"
|
|
6
|
-
import {cssReset} from "../../
|
|
6
|
+
import {cssReset, useName, useOnce, useStyles} from "../../view/index.js"
|
|
7
7
|
|
|
8
|
-
export const LoadersView =
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export const LoadersView = shadow(() => {
|
|
9
|
+
useName("loaders")
|
|
10
|
+
useStyles(cssReset, styles)
|
|
11
11
|
|
|
12
|
-
const op =
|
|
12
|
+
const op = useOnce(() => Op.loading())
|
|
13
13
|
|
|
14
|
-
const library =
|
|
14
|
+
const library = useOnce(() =>
|
|
15
15
|
Object.entries(loaders.anims).map(([key, anim]) => ({
|
|
16
16
|
key,
|
|
17
17
|
loader: loaders.make(anim)
|
package/s/index.html.ts
CHANGED
|
@@ -1,38 +1,35 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import {template, html, socialCard} from "@e280/scute"
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
export default template(import.meta.url, async orb => html`
|
|
5
|
+
<!doctype html>
|
|
6
|
+
<html>
|
|
7
|
+
<head>
|
|
8
|
+
<meta charset="utf-8"/>
|
|
9
|
+
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
10
|
+
<meta name="darkreader-lock"/>
|
|
11
|
+
<style>@layer base{html{background:#000}}</style>
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
favicon,
|
|
14
|
-
dark: true,
|
|
15
|
-
socialCard: {
|
|
16
|
-
themeColor: "#95ff7b",
|
|
17
|
-
title,
|
|
18
|
-
description,
|
|
19
|
-
siteName: "@e280/sly",
|
|
20
|
-
image: "https://" + domain + favicon,
|
|
21
|
-
},
|
|
13
|
+
<title>sly</title>
|
|
14
|
+
<link rel="icon" href="/assets/favicon.png"/>
|
|
15
|
+
<link rel="stylesheet" href="${orb.hashurl("demo/demo.css")}"/>
|
|
16
|
+
<script type="module" src="${orb.hashurl("demo/demo.bundle.min.js")}"></script>
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
18
|
+
${socialCard({
|
|
19
|
+
themeColor: "#95ff7b",
|
|
20
|
+
title: "sly",
|
|
21
|
+
description: "mischievous shadow views",
|
|
22
|
+
siteName: "@e280/sly",
|
|
23
|
+
image: "https://sly.e280.org/assets/favicon.png",
|
|
24
|
+
})}
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<img class=icon alt="" src="/assets/favicon.png"/>
|
|
28
|
+
<h1>sly testing page</h1>
|
|
29
|
+
<p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
|
|
30
|
+
<p class=lil>v${orb.packageVersion()}</p>
|
|
31
|
+
<div class="demo"></div>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
34
|
+
`)
|
|
38
35
|
|
package/s/index.ts
CHANGED
package/s/loaders/make.ts
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
|
|
2
2
|
import {css} from "lit"
|
|
3
3
|
import {nap, cycle} from "@e280/stz"
|
|
4
|
-
|
|
5
|
-
import {view} from "../../view/view.js"
|
|
6
4
|
import {Content} from "../../view/types.js"
|
|
7
|
-
import {cssReset} from "../../
|
|
5
|
+
import {cssReset, shadow, useMount, useName, useSignal, useStyles} from "../../view/index.js"
|
|
8
6
|
|
|
9
7
|
export function makeAsciiAnim(hz: number, frames: string[]): () => Content {
|
|
10
8
|
return () => AsciiAnim({hz, frames})
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
export const AsciiAnim =
|
|
11
|
+
export const AsciiAnim = shadow(({hz, frames}: {
|
|
14
12
|
hz: number,
|
|
15
13
|
frames: string[],
|
|
16
14
|
}) => {
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
useName("loading")
|
|
17
|
+
useStyles(cssReset, style)
|
|
20
18
|
|
|
21
|
-
const frame =
|
|
19
|
+
const frame = useSignal(0)
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
useMount(() => cycle(async() => {
|
|
24
22
|
await nap(1000 / hz)
|
|
25
23
|
const next = frame.get() + 1
|
|
26
24
|
frame.set(next >= frames.length ? 0 : next)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
|
|
2
2
|
import {css, html} from "lit"
|
|
3
|
-
import {
|
|
4
|
-
import {cssReset} from "../../
|
|
3
|
+
import {shadow} from "../../view/shadow.js"
|
|
4
|
+
import {cssReset, useName, useStyles} from "../../view/index.js"
|
|
5
5
|
|
|
6
|
-
export const ErrorDisplay =
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export const ErrorDisplay = shadow((error: any) => {
|
|
7
|
+
useName("error")
|
|
8
|
+
useStyles(cssReset, style)
|
|
9
9
|
|
|
10
10
|
if (typeof error === "string")
|
|
11
11
|
return error
|
|
@@ -18,9 +18,9 @@ export const ErrorDisplay = view(use => (error: any) => {
|
|
|
18
18
|
})
|
|
19
19
|
|
|
20
20
|
const style = css`
|
|
21
|
-
:host {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
21
|
+
:host {
|
|
22
|
+
font-family: monospace;
|
|
23
|
+
color: red;
|
|
24
|
+
}
|
|
25
25
|
`
|
|
26
26
|
|
package/s/tests.test.ts
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
import {css, CSSResultGroup} from "lit"
|
|
3
|
+
|
|
4
|
+
export const cssReset: CSSResultGroup = css`
|
|
5
|
+
* {
|
|
6
|
+
margin: 0;
|
|
7
|
+
padding: 0;
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
|
|
10
|
+
scrollbar-width: thin;
|
|
11
|
+
scrollbar-color: #888 transparent;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
::-webkit-scrollbar { width: 8px; }
|
|
15
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
16
|
+
::-webkit-scrollbar-thumb { background: #888; border-radius: 1em; }
|
|
17
|
+
::-webkit-scrollbar-thumb:hover { background: #999; }
|
|
18
|
+
`
|
|
19
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
import {Hookscope} from "./hookscope.js"
|
|
3
|
+
|
|
4
|
+
export class Hooks {
|
|
5
|
+
#scopes: Hookscope[] = []
|
|
6
|
+
|
|
7
|
+
get scope() {
|
|
8
|
+
const scope = this.#scopes.at(-1)
|
|
9
|
+
if (!scope) throw new Error("hooks must be called within a render fn")
|
|
10
|
+
return scope
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
increment() {
|
|
14
|
+
const scope = this.scope
|
|
15
|
+
const position = scope.position++
|
|
16
|
+
return {scope, position}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
wrap<Ret>(scope: Hookscope, fn: () => Ret) {
|
|
20
|
+
scope.position = 0
|
|
21
|
+
this.#scopes.push(scope)
|
|
22
|
+
try { return fn() }
|
|
23
|
+
finally { this.#scopes.pop() }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const hooks: Hooks = (globalThis as any)[Symbol.for("e280.hooks")] ??= new Hooks()
|
|
28
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
import {GMap} from "@e280/stz"
|
|
3
|
+
import {Mounts} from "../use-mount.js"
|
|
4
|
+
import {LightCx, ShadowCx} from "../../parts/cx.js"
|
|
5
|
+
|
|
6
|
+
export class Hookscope {
|
|
7
|
+
position = 0
|
|
8
|
+
values = new GMap<number, any>()
|
|
9
|
+
mounts = new Mounts()
|
|
10
|
+
constructor(public cx: LightCx | ShadowCx) {}
|
|
11
|
+
}
|
|
12
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
import {CSSResultGroup} from "lit"
|
|
3
|
+
import {useShadow} from "./use-cx.js"
|
|
4
|
+
import {useOnce} from "./use-once.js"
|
|
5
|
+
import {applyStyles} from "../parts/apply-styles.js"
|
|
6
|
+
|
|
7
|
+
/** attach stylesheets to the shadow root */
|
|
8
|
+
export function useCss(...styles: CSSResultGroup[]) {
|
|
9
|
+
const shadow = useShadow()
|
|
10
|
+
useOnce(() => applyStyles(shadow, styles))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const useStyles = useCss
|
|
14
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
import {ShadowCx} from "../parts/cx.js"
|
|
3
|
+
import {hooks} from "./plumbing/hooks.js"
|
|
4
|
+
|
|
5
|
+
function useCx() {
|
|
6
|
+
const {scope} = hooks.increment()
|
|
7
|
+
return scope.cx
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function useShadowCx() {
|
|
11
|
+
const cx = useCx()
|
|
12
|
+
if (!(cx instanceof ShadowCx))
|
|
13
|
+
throw new Error("this hook only works on shadow views (but was called in a light view)")
|
|
14
|
+
return cx
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** return the current count of how many times this view has been rendered (starts at 0) */
|
|
18
|
+
export function useCount() {
|
|
19
|
+
return useCx().count
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** return a function that triggers the view to rerender */
|
|
23
|
+
export function useRender() {
|
|
24
|
+
return useCx().render
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** return a promise that resolves after the next render is complete */
|
|
28
|
+
export function useRendered() {
|
|
29
|
+
return useCx().rendered.promise
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** return the shadow view's host element */
|
|
33
|
+
export function useHost() {
|
|
34
|
+
return useShadowCx().host
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** return the shadow root */
|
|
38
|
+
export function useShadow() {
|
|
39
|
+
return useShadowCx().shadow
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
import {useRef} from "./use-ref.js"
|
|
3
|
+
import {useMount} from "./use-mount.js"
|
|
4
|
+
|
|
5
|
+
/** mount/unmount lifecycle, but also return a value */
|
|
6
|
+
export function useLife<Value>(fn: () => [value: Value, dispose: () => void]) {
|
|
7
|
+
const ref = useRef<Value>(undefined as Value)
|
|
8
|
+
|
|
9
|
+
useMount(() => {
|
|
10
|
+
const [value, dispose] = fn()
|
|
11
|
+
ref.value = value
|
|
12
|
+
return dispose
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
return ref.value
|
|
16
|
+
}
|
|
17
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
import {useOnce} from "./use-once.js"
|
|
3
|
+
import {hooks} from "./plumbing/hooks.js"
|
|
4
|
+
|
|
5
|
+
export function useMount(fn: () => () => void) {
|
|
6
|
+
const {scope} = hooks.increment()
|
|
7
|
+
return useOnce(() => scope.mounts.mount(fn))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class Mounts {
|
|
11
|
+
#mounters: (() => () => void)[] = []
|
|
12
|
+
#unmounters: (() => void)[] = []
|
|
13
|
+
|
|
14
|
+
mount(mount: () => () => void) {
|
|
15
|
+
this.#mounters.push(mount)
|
|
16
|
+
this.#unmounters.push(mount())
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
unmountAll() {
|
|
20
|
+
for (const unmount of this.#unmounters)
|
|
21
|
+
unmount()
|
|
22
|
+
this.#unmounters = []
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
remountAll() {
|
|
26
|
+
for (const mount of this.#mounters)
|
|
27
|
+
this.#unmounters.push(mount())
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
import {Op} from "../../ops/op.js"
|
|
3
|
+
import {useOnce} from "./use-once.js"
|
|
4
|
+
|
|
5
|
+
export function useOp<Value>(fn: () => Promise<Value>) {
|
|
6
|
+
return useOnce(() => Op.load(fn))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function useOpPromise<Value>(promise: Promise<Value>) {
|
|
10
|
+
return useOnce(() => Op.promise(promise))
|
|
11
|
+
}
|
|
12
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
import {signal} from "@e280/strata"
|
|
3
|
+
import {useOnce} from "./use-once.js"
|
|
4
|
+
|
|
5
|
+
export function useSignal<Value>(value: Value) {
|
|
6
|
+
return useOnce(() => signal(value))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function useDerived<Value>(fn: () => Value) {
|
|
10
|
+
return useOnce(() => signal.derived(fn))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function useLazy<Value>(fn: () => Value) {
|
|
14
|
+
return useOnce(() => signal.lazy(fn))
|
|
15
|
+
}
|
|
16
|
+
|