Skip to content

Commit 47ddf99

Browse files
committed
incredi: full circle view->component->view omg!
1 parent 2e9cb93 commit 47ddf99

File tree

7 files changed

+48
-16
lines changed

7 files changed

+48
-16
lines changed

s/demo/demo.bundle.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ import {dom} from "../dom/dom.js"
33
import {DemoView} from "./views/demo.js"
44
import {CounterView} from "./views/counter.js"
55
import {IncrediElement} from "./views/incredi.js"
6+
import {BackwardsElement} from "./views/backwards.js"
67

78
dom.in(".demo").render(DemoView())
89

910
dom.register({
1011
IncrediElement,
12+
BackwardsElement,
1113
DemoCounter: CounterView.component(el => [
1214
dom.attrs(el).number.initial ?? 0,
1315
]),
1416
})
1517

18+
dom<BackwardsElement>("backwards-element").speed = 2
19+
1620
console.log("🦝 sly")
1721

s/demo/views/backwards.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
import {html} from "lit"
3+
import {view} from "../../views/view.js"
4+
5+
export class BackwardsElement extends view
6+
.component<{speed?: number}>()
7+
.props<[speed: number]>(el => [el.speed ?? 1])
8+
.declare(use => speed => {
9+
10+
const $count = use.signal(0)
11+
const increment = () => $count($count() + speed)
12+
13+
return html`
14+
<span>${$count()}</span>
15+
<button @click="${increment}">+${speed}</button>
16+
`
17+
}) {}
18+
19+
export const BackwardsView = BackwardsElement.view
20+

s/demo/views/demo.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {css, html} from "lit"
33
import {view} from "../../views/view.js"
44
import {CounterView} from "./counter.js"
55
import {LoadersView} from "./loaders.js"
6+
import {BackwardsView} from "./backwards.js"
67
import {cssReset} from "../../views/css-reset.js"
78

89
export const DemoView = view(use => () => {
@@ -11,6 +12,7 @@ export const DemoView = view(use => () => {
1112

1213
return html`
1314
${CounterView.props(2).children("view").render()}
15+
${BackwardsView(3)}
1416
${LoadersView()}
1517
`
1618
})

s/demo/views/incredi.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {BaseElement} from "../../views/base-element.js"
88

99
export class IncrediElement extends BaseElement {
1010
static styles = css`span{color:orange}`
11+
1112
attrs = dom.attrs(this).spec({value: Number})
1213
something = {whatever: "rofl"}
1314

s/index.html.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export default ssg.page(import.meta.url, async orb => ({
3030
<p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
3131
<p class=lil>v${orb.packageVersion()}</p>
3232
<incredi-element></incredi-element>
33+
<backwards-element></backwards-element>
3334
<demo-counter initial="-1">component</demo-counter>
3435
<div class=demo></div>
3536
`,

s/views/types.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11

2-
import {Constructor} from "@e280/stz"
32
import {DirectiveResult} from "lit/directive.js"
43
import {CSSResultGroup, TemplateResult} from "lit"
54

@@ -8,15 +7,24 @@ import {Use} from "./use.js"
87
export type Content = TemplateResult | DirectiveResult | HTMLElement | string | null | undefined | void | Content[]
98
export type AttrValue = string | boolean | number | undefined | null | void
109

11-
export type Elmix<Mix extends Partial<ViewComponent>> = Mix & ViewComponent & HTMLElement
10+
export type ViewComponent<Mix extends {} = {}> = Mix & {
11+
renderNow(): void
12+
render: () => void
13+
} & HTMLElement
14+
15+
export type ViewComponentClass<Mix extends {}, Props extends any[]> = {
16+
view: View<Props>
17+
new(): ViewComponent<Mix>
18+
}
1219

1320
export type ComponentFn = (use: Use) => Content
1421
export type ViewFn<Props extends any[]> = (use: Use) => (...props: Props) => Content
1522
export type BasicView<Props extends any[]> = (...props: Props) => DirectiveResult<any>
23+
1624
export type View<Props extends any[]> = BasicView<Props> & {
1725
props: (...props: Props) => ViewChain
18-
component: <Mix extends Partial<ViewComponent>>(fn: (el: Elmix<Mix>) => Props) => (
19-
(Constructor<Elmix<Mix>> & typeof HTMLElement)
26+
component: <Mix extends {}>(fn: (el: ViewComponent<Mix>) => Props) => (
27+
ViewComponentClass<Mix, Props>
2028
)
2129
}
2230

@@ -38,8 +46,3 @@ export type ViewContext = {
3846
attrs: Record<string, AttrValue>
3947
}
4048

41-
export type ViewComponent = {
42-
renderNow(): void
43-
render: () => void
44-
} & HTMLElement
45-

s/views/view.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
import {render} from "lit"
3-
import {Constructor, debounce, MapG} from "@e280/stz"
3+
import {debounce, MapG} from "@e280/stz"
44
import {directive} from "lit/directive.js"
55
import {tracker} from "@e280/strata/tracker"
66
import {AsyncDirective} from "lit/async-directive.js"
@@ -10,7 +10,7 @@ import {applyAttrs} from "./utils/apply-attrs.js"
1010
import {AttrWatcher} from "./utils/attr-watcher.js"
1111
import {applyStyles} from "./utils/apply-styles.js"
1212
import {Use, _wrap, _disconnect, _reconnect} from "./use.js"
13-
import {AttrValue, Content, View, ViewFn, ViewSettings, ViewContext, ViewComponent, Elmix} from "./types.js"
13+
import {AttrValue, Content, View, ViewFn, ViewSettings, ViewContext, ViewComponent, ViewComponentClass} from "./types.js"
1414

1515
export const view = setupView({mode: "open"})
1616
export class SlyView extends HTMLElement {}
@@ -135,8 +135,9 @@ function setupView(settings: ViewSettings) {
135135
return chain
136136
}
137137

138-
rendy.component = <El extends Partial<ViewComponent>>(fn: (el: El) => Props) => {
138+
rendy.component = <Mix extends {} = {}>(fn: (el: Mix) => Props) => {
139139
return class VComponent extends HTMLElement implements ViewComponent {
140+
static view = rendy
140141
#context = freshViewContext()
141142
#directive = directive(
142143
make({
@@ -159,17 +160,17 @@ function setupView(settings: ViewSettings) {
159160
render(this.#directive(this.#context, props), this)
160161
}
161162
}
162-
} as any as (Constructor<El> & typeof HTMLElement)
163+
} as any as ViewComponentClass<Mix, Props>
163164
}
164165

165166
return rendy
166167
}
167168

168169
view.declare = view
169170
view.settings = (settings2: Partial<ViewSettings>) => setupView({...settings, ...settings2})
170-
view.component = <Mix extends Partial<ViewComponent>>() => ({
171-
props: <Props extends any[]>(elfn: (el: Elmix<Mix>) => Props) => ({
172-
declare: (fn: ViewFn<Props>) => view(fn).component(elfn)
171+
view.component = <Mix extends {}>() => ({
172+
props: <Props extends any[]>(elfn: (el: ViewComponent<Mix>) => Props) => ({
173+
declare: (fn: ViewFn<Props>) => view(fn).component(elfn),
173174
}),
174175
})
175176
return view

0 commit comments

Comments
 (0)