@e280/sly 0.0.0-4 → 0.0.0-5
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 +99 -88
- package/package.json +2 -2
- package/s/demo/demo.bundle.ts +3 -47
- package/s/demo/demo.css +13 -6
- package/s/demo/views/counter.ts +42 -0
- package/s/demo/views/demo.ts +25 -0
- package/s/demo/views/loaders.ts +58 -0
- package/s/features/op/loaders/make-loader.ts +18 -0
- package/s/features/op/loaders/parts/anims.ts +277 -0
- package/s/features/op/loaders/parts/ascii-anim.ts +38 -0
- package/s/features/{loady → op/loaders}/parts/error-display.ts +10 -10
- package/s/features/op/op.ts +42 -20
- package/s/features/op/podium.ts +67 -0
- package/s/features/views/use.ts +6 -5
- package/s/features/views/view.ts +12 -5
- package/s/index.html.ts +2 -2
- package/s/index.ts +4 -3
- package/x/demo/demo.bundle.js +2 -36
- package/x/demo/demo.bundle.js.map +1 -1
- package/x/demo/demo.bundle.min.js +61 -12
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/demo/demo.css +13 -6
- package/x/demo/views/counter.d.ts +1 -0
- package/x/demo/views/counter.js +34 -0
- package/x/demo/views/counter.js.map +1 -0
- package/x/demo/views/demo.d.ts +1 -0
- package/x/demo/views/demo.js +21 -0
- package/x/demo/views/demo.js.map +1 -0
- package/x/demo/views/loaders.d.ts +1 -0
- package/x/demo/views/loaders.js +50 -0
- package/x/demo/views/loaders.js.map +1 -0
- package/x/features/op/loaders/make-loader.d.ts +5 -0
- package/x/features/op/loaders/make-loader.js +7 -0
- package/x/features/op/loaders/make-loader.js.map +1 -0
- package/x/features/op/loaders/parts/anims.d.ts +24 -0
- package/x/features/op/loaders/parts/anims.js +251 -0
- package/x/features/op/loaders/parts/anims.js.map +1 -0
- package/x/features/op/loaders/parts/ascii-anim.d.ts +6 -0
- package/x/features/op/loaders/parts/ascii-anim.js +26 -0
- package/x/features/op/loaders/parts/ascii-anim.js.map +1 -0
- package/x/features/op/loaders/parts/error-display.d.ts +1 -0
- package/x/features/{loady → op/loaders}/parts/error-display.js +9 -9
- package/x/features/op/loaders/parts/error-display.js.map +1 -0
- package/x/features/op/op.d.ts +12 -3
- package/x/features/op/op.js +33 -17
- package/x/features/op/op.js.map +1 -1
- package/x/features/op/podium.d.ts +9 -0
- package/x/features/op/podium.js +53 -0
- package/x/features/op/podium.js.map +1 -0
- package/x/features/views/use.d.ts +4 -3
- package/x/features/views/use.js +7 -5
- package/x/features/views/use.js.map +1 -1
- package/x/features/views/view.js +11 -5
- package/x/features/views/view.js.map +1 -1
- package/x/index.d.ts +4 -3
- package/x/index.html +17 -10
- package/x/index.html.js +2 -2
- package/x/index.html.js.map +1 -1
- package/x/index.js +4 -3
- package/x/index.js.map +1 -1
- package/s/features/loady/ascii-loader.ts +0 -38
- package/s/features/loady/parts/ascii-anim.ts +0 -27
- package/s/features/loady/parts/ascii-loader.ts +0 -14
- package/s/features/op/pod.ts +0 -19
- package/x/features/loady/ascii-loader.d.ts +0 -5
- package/x/features/loady/ascii-loader.js +0 -33
- package/x/features/loady/ascii-loader.js.map +0 -1
- package/x/features/loady/parts/ascii-anim.d.ts +0 -1
- package/x/features/loady/parts/ascii-anim.js +0 -21
- package/x/features/loady/parts/ascii-anim.js.map +0 -1
- package/x/features/loady/parts/ascii-loader.d.ts +0 -3
- package/x/features/loady/parts/ascii-loader.js +0 -10
- package/x/features/loady/parts/ascii-loader.js.map +0 -1
- package/x/features/loady/parts/error-display.d.ts +0 -1
- package/x/features/loady/parts/error-display.js.map +0 -1
- package/x/features/op/pod.d.ts +0 -5
- package/x/features/op/pod.js +0 -16
- package/x/features/op/pod.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
<div align="center"><img alt="" width="256" src="./assets/favicon.png"/></div>
|
|
3
3
|
|
|
4
4
|
# 🦝 sly — mischievous shadow views
|
|
5
|
-
|
|
5
|
+
> testing page at https://sly.e280.org/
|
|
6
|
+
|
|
7
|
+
- 🪒 lean view framework for [lit](https://lit.dev/) web devs
|
|
6
8
|
- 🌅 sly is the successor to [@benev/slate](https://github.com/benevolent-games/slate)
|
|
7
9
|
- 🏂 commonly used with stz standard library [@e280/stz](https://github.com/e280/stz)
|
|
8
10
|
- ⛏️ integrates signals and state trees from [@e280/strata](https://github.com/e280/strata)
|
|
@@ -11,8 +13,7 @@
|
|
|
11
13
|
|
|
12
14
|
<br/>
|
|
13
15
|
|
|
14
|
-
## 🦝 INSTALL SLY AND
|
|
15
|
-
they all super work together.
|
|
16
|
+
## 🦝 INSTALL SLY AND PALS
|
|
16
17
|
|
|
17
18
|
```sh
|
|
18
19
|
npm install @e280/sly @e280/stz @e280/strata lit
|
|
@@ -20,50 +21,90 @@ npm install @e280/sly @e280/stz @e280/strata lit
|
|
|
20
21
|
|
|
21
22
|
<br/>
|
|
22
23
|
|
|
23
|
-
## 🦝 VIEWS
|
|
24
|
+
## 🦝 SLY VIEWS
|
|
24
25
|
views are the crown jewel of sly. shadow-dom'd. hooks-based. fancy ergonomics. not components.
|
|
25
26
|
|
|
26
|
-
views are leaner than web components.. no dom registration, string tag names.. just import 'em, and the types work.. web components are fine, but they're for providing html authors with entrypoints to your cool widgets.. whereas views are the building blocks for frontend app devs.
|
|
27
|
+
views are leaner than web components.. no dom registration, no string tag names.. just import 'em, and the types work.. web components are fine, but they're for providing html authors with entrypoints to your cool widgets.. whereas views are the building blocks for frontend app devs.
|
|
27
28
|
|
|
28
29
|
sly views are wired to automatically rerender whenever they're using any state stuff from [@e280/strata](https://github.com/e280/strata).
|
|
29
30
|
|
|
30
31
|
### 🍋 basic view example
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
-
|
|
32
|
+
- views are hooks-based functional components with a [shadow root](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM)
|
|
33
|
+
- **declaring a view**
|
|
34
|
+
```ts
|
|
35
|
+
import {view} from "@e280/sly"
|
|
36
|
+
import {html, css} from "lit"
|
|
37
|
+
|
|
38
|
+
export const CounterView = view(use => (start: number) => {
|
|
39
|
+
use.name("counter")
|
|
40
|
+
use.styles(css`p {color: green}`)
|
|
41
|
+
const count = use.signal(start)
|
|
42
|
+
|
|
43
|
+
return html`
|
|
44
|
+
<p>count ${count()}</p>
|
|
45
|
+
<button @click="${() => { count.value++ }}"></button>
|
|
46
|
+
`
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
- each view renders into a `<sly-view>` host, with the provided `name` set as its view attribute, eg `<sly-view view="counter">`
|
|
50
|
+
- **injecting a view into the dom**
|
|
51
|
+
```ts
|
|
52
|
+
import {render, html} from "lit"
|
|
53
|
+
import {CounterView} from "./my-counter.js"
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
const content = html`
|
|
56
|
+
<h1>my demo page</h1>
|
|
57
|
+
${CounterView(1)}
|
|
58
|
+
`
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
${CounterView(1)}
|
|
59
|
-
`
|
|
60
|
+
render(content, document.querySelector(".app")!)
|
|
61
|
+
```
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
### 🍋 view declaration settings
|
|
64
|
+
- special settings for views at declaration-time
|
|
65
|
+
```ts
|
|
66
|
+
import {view} from "@e280/sly"
|
|
67
|
+
import {html} from "lit"
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
export const CoolView = view
|
|
70
|
+
.settings({mode: "open", delegatesFocus: true})
|
|
71
|
+
.view(use => (greeting: string) => {
|
|
72
|
+
|
|
73
|
+
return html`😎 ${greeting} <slot></slot>`
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
- these `settings` like `mode` and `delegatesFocus` are [attachShadow params](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#parameters)
|
|
77
|
+
- note the `<slot></slot>` we'll use in the next example lol
|
|
66
78
|
|
|
79
|
+
### 🍋 view injection options
|
|
80
|
+
- options for views at the template injection site
|
|
81
|
+
```ts
|
|
82
|
+
import {render, html} from "lit"
|
|
83
|
+
import {CoolView} from "./cool-view.js"
|
|
84
|
+
|
|
85
|
+
const content = html`
|
|
86
|
+
<h2>super cool example</h2>
|
|
87
|
+
${CoolView
|
|
88
|
+
.attr("class", "hero")
|
|
89
|
+
.children(html`<em>spongebob</em>`)
|
|
90
|
+
.props("hello")}
|
|
91
|
+
`
|
|
92
|
+
|
|
93
|
+
render(content, document.querySelector(".app")!)
|
|
94
|
+
```
|
|
95
|
+
- `attr` — set html attributes on the `<sly-view>` host element
|
|
96
|
+
- `children` — nested content in the host element, can be [slotted](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)
|
|
97
|
+
- `props` — finally inject the view by providing its props
|
|
98
|
+
|
|
99
|
+
### 🍋 view `use` reference
|
|
100
|
+
- **use.name** — set the "view" attr value, eg `<sly-view view="squarepants">`
|
|
101
|
+
```ts
|
|
102
|
+
use.name("squarepants")
|
|
103
|
+
```
|
|
104
|
+
- **use.styles** — attach stylesheets into the view's shadow dom
|
|
105
|
+
```ts
|
|
106
|
+
use.styles(css1, css2, css3)
|
|
107
|
+
```
|
|
67
108
|
- **use.signal** — create a [strata signal](https://github.com/e280/strata)
|
|
68
109
|
```ts
|
|
69
110
|
const count = use.signal(1)
|
|
@@ -103,25 +144,30 @@ render(content, document.querySelector(".app")!)
|
|
|
103
144
|
|
|
104
145
|
v //-> 123
|
|
105
146
|
```
|
|
106
|
-
- **use.
|
|
147
|
+
- **use.render** — force a hard render (not debounced)
|
|
107
148
|
```ts
|
|
108
|
-
use.
|
|
149
|
+
use.render()
|
|
109
150
|
```
|
|
110
|
-
- **use.
|
|
111
|
-
```ts
|
|
112
|
-
use.styles(css1, css2, css3)
|
|
113
|
-
```
|
|
114
|
-
- **use.rendered** — promise that resolves *after* view has rendered
|
|
151
|
+
- **use.rendered** — promise that resolves *after* the next render
|
|
115
152
|
```ts
|
|
116
153
|
use.rendered.then(() => {
|
|
117
154
|
const slot = use.shadow.querySelector("slot")!
|
|
118
155
|
console.log(slot)
|
|
119
156
|
})
|
|
120
157
|
```
|
|
158
|
+
- **use.op.fn** — start with an op based on an async fn
|
|
159
|
+
```ts
|
|
160
|
+
const op = use.op.fn(async() => {
|
|
161
|
+
await nap(5000)
|
|
162
|
+
return 123
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
- **use.op.promise** — start with an op based on a promise
|
|
166
|
+
```ts
|
|
167
|
+
const op = use.op.promise(doAsyncWork())
|
|
168
|
+
```
|
|
121
169
|
|
|
122
170
|
### 🍋 neat tricks to impress the ladies
|
|
123
|
-
> common patterns and snippets
|
|
124
|
-
|
|
125
171
|
- make a ticker — mount, repeat, and nap
|
|
126
172
|
```ts
|
|
127
173
|
import {repeat, nap} from "@e280/stz"
|
|
@@ -141,55 +187,20 @@ render(content, document.querySelector(".app")!)
|
|
|
141
187
|
}))
|
|
142
188
|
```
|
|
143
189
|
|
|
144
|
-
### 🍋 view declaration settings
|
|
145
|
-
> special settings for views at declaration-time
|
|
146
|
-
|
|
147
|
-
```ts
|
|
148
|
-
import {view} from "@e280/sly"
|
|
149
|
-
import {html} from "lit"
|
|
150
|
-
|
|
151
|
-
export const CoolView = view
|
|
152
|
-
.settings({mode: "open", delegatesFocus: true})
|
|
153
|
-
.view(use => (greeting: string) => {
|
|
154
|
-
|
|
155
|
-
return html`😎 ${greeting} <slot></slot>`
|
|
156
|
-
})
|
|
157
|
-
```
|
|
158
|
-
- these `settings` like `mode` and `delegatesFocus` are [attachShadow params](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#parameters)
|
|
159
|
-
- note the `<slot></slot>` we'll use in the next example lol
|
|
160
|
-
|
|
161
|
-
### 🍋 view injection options
|
|
162
|
-
> options for views at the template injection site
|
|
163
|
-
|
|
164
|
-
```ts
|
|
165
|
-
import {render, html} from "lit"
|
|
166
|
-
import {CoolView} from "./cool-view.js"
|
|
167
|
-
|
|
168
|
-
const content = html`
|
|
169
|
-
<h2>super cool example</h2>
|
|
170
|
-
${CoolView
|
|
171
|
-
.attr("class", "hero")
|
|
172
|
-
.children(html`<em>spongebob</em>`)
|
|
173
|
-
.props("hello")}
|
|
174
|
-
`
|
|
175
|
-
|
|
176
|
-
render(content, document.querySelector(".app")!)
|
|
177
|
-
```
|
|
178
|
-
- `attr` — set html attributes on the `<sly-view>` host element
|
|
179
|
-
- `children` — nested content in the host element, can be [slotted](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)
|
|
180
|
-
- `props` — finally inject the view by providing its props
|
|
181
|
-
|
|
182
190
|
<br/>
|
|
183
191
|
|
|
184
|
-
## 🦝 OPS
|
|
185
|
-
> ***TODO*** *
|
|
186
|
-
- `Pod` is a type for
|
|
192
|
+
## 🦝 SLY OPS, PODS, AND LOADERS
|
|
193
|
+
> ***TODO*** *we need to write real docs for this, lol*
|
|
194
|
+
- `Pod` is a type for loading/ready/error states
|
|
195
|
+
- `podium` is a tool with fns for working with pods
|
|
187
196
|
- `Op` class wraps a pod signal and has some ergonomic fns
|
|
188
|
-
- `
|
|
197
|
+
- `makeLoader(anims.bar2)` makes it easy to create a loader
|
|
198
|
+
- see the available `anims` on the testing page: https://sly.e280.org/
|
|
199
|
+
- a loader's job is to render an op, with a nice loading anim and error display view
|
|
189
200
|
|
|
190
201
|
<br/>
|
|
191
202
|
|
|
192
|
-
## 🧑💻
|
|
203
|
+
## 🧑💻 SLY BY E280
|
|
193
204
|
reward us with github stars
|
|
194
205
|
build with us at https://e280.org/ but only if you're cool
|
|
195
206
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e280/sly",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-5",
|
|
4
4
|
"description": "web shadow views",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "run-s _clean _ln _tsc _scute",
|
|
29
|
-
"
|
|
29
|
+
"start": "octo 'scute -vw' 'tsc -w' 'node --watch x/tests.test.js' 'http-server x'",
|
|
30
30
|
"count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +",
|
|
31
31
|
"test": "node x/tests.test.js",
|
|
32
32
|
"test-inspect": "node inspect x/tests.test.js",
|
package/s/demo/demo.bundle.ts
CHANGED
|
@@ -1,52 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
3
|
-
import {css, html, render} from "lit"
|
|
4
|
-
|
|
2
|
+
import {DemoView} from "./views/demo.js"
|
|
5
3
|
import {$} from "../features/dom/dollar.js"
|
|
6
|
-
import {view} from "../features/views/view.js"
|
|
7
|
-
import {cssReset} from "../features/views/css-reset.js"
|
|
8
|
-
import {loady} from "../features/loady/ascii-loader.js"
|
|
9
|
-
|
|
10
|
-
console.log("🦝 sly")
|
|
11
|
-
|
|
12
|
-
const styles = css`
|
|
13
|
-
:host {
|
|
14
|
-
display: flex;
|
|
15
|
-
flex-direction: column;
|
|
16
|
-
justify-content: center;
|
|
17
|
-
text-align: center;
|
|
18
|
-
}
|
|
19
|
-
`
|
|
20
|
-
|
|
21
|
-
const MyView = view(use => (greeting: string) => {
|
|
22
|
-
use.name("my-view")
|
|
23
|
-
use.styles(cssReset, styles)
|
|
24
|
-
const count = use.signal(0)
|
|
25
4
|
|
|
26
|
-
|
|
27
|
-
await nap(1000)
|
|
28
|
-
count.value++
|
|
29
|
-
}))
|
|
5
|
+
$.render($(".demo"), DemoView())
|
|
30
6
|
|
|
31
|
-
|
|
32
|
-
console.log("slot", $("slot", use.shadow))
|
|
33
|
-
}))
|
|
34
|
-
|
|
35
|
-
const op = use.op.fn(async() => {
|
|
36
|
-
await nap(5000)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
return html`
|
|
40
|
-
<p>${greeting} <slot></slot> ${count()}</p>
|
|
41
|
-
<p>${loady.dots(op, () => "op loaded")}</p>
|
|
42
|
-
`
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
render(
|
|
46
|
-
MyView
|
|
47
|
-
.attr("class", "incredi")
|
|
48
|
-
.children("world")
|
|
49
|
-
.props("hello"),
|
|
50
|
-
$(".demo"),
|
|
51
|
-
)
|
|
7
|
+
console.log("🦝 sly")
|
|
52
8
|
|
package/s/demo/demo.css
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
:root {
|
|
6
6
|
--prime: #1eff00;
|
|
7
7
|
--accent: #387d42;
|
|
8
|
+
--pill: #12763959;
|
|
8
9
|
--bg: #0e2316;
|
|
9
10
|
--link: cyan;
|
|
10
11
|
}
|
|
@@ -51,15 +52,12 @@
|
|
|
51
52
|
|
|
52
53
|
@layer page {
|
|
53
54
|
:root {
|
|
54
|
-
color-scheme: dark;
|
|
55
|
-
|
|
56
|
-
padding: 5vw 0.5em;
|
|
57
|
-
min-height: 100%;
|
|
58
|
-
scrollbar-gutter: stable;
|
|
59
|
-
|
|
60
55
|
font-size: 21px;
|
|
61
56
|
font-family: sans-serif;
|
|
62
57
|
|
|
58
|
+
color-scheme: dark;
|
|
59
|
+
scrollbar-gutter: stable;
|
|
60
|
+
|
|
63
61
|
color: color-mix(in lch, var(--prime), #fff8 50%);
|
|
64
62
|
background: radial-gradient(
|
|
65
63
|
circle,
|
|
@@ -69,6 +67,11 @@
|
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
body {
|
|
70
|
+
width: 100%;
|
|
71
|
+
max-width: 32em;
|
|
72
|
+
margin: auto;
|
|
73
|
+
padding: 1em;
|
|
74
|
+
|
|
72
75
|
display: flex;
|
|
73
76
|
flex-direction: column;
|
|
74
77
|
align-items: center;
|
|
@@ -88,6 +91,10 @@
|
|
|
88
91
|
font-size: 0.8em;
|
|
89
92
|
}
|
|
90
93
|
|
|
94
|
+
.demo {
|
|
95
|
+
width: 100%;
|
|
96
|
+
}
|
|
97
|
+
|
|
91
98
|
:not(:defined) {
|
|
92
99
|
display: none;
|
|
93
100
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
import {css, html} from "lit"
|
|
3
|
+
import {repeat} from "@e280/stz"
|
|
4
|
+
|
|
5
|
+
import {view} from "../../features/views/view.js"
|
|
6
|
+
import {cssReset} from "../../features/views/css-reset.js"
|
|
7
|
+
|
|
8
|
+
export const CounterView = view(use => () => {
|
|
9
|
+
use.name("counter")
|
|
10
|
+
use.styles(cssReset, styles)
|
|
11
|
+
|
|
12
|
+
const start = use.once(() => Date.now())
|
|
13
|
+
const seconds = use.signal(0)
|
|
14
|
+
|
|
15
|
+
use.mount(() => repeat(async() => {
|
|
16
|
+
const since = Date.now() - start
|
|
17
|
+
seconds(Math.floor(since / 1000))
|
|
18
|
+
}))
|
|
19
|
+
|
|
20
|
+
const count = use.signal(0)
|
|
21
|
+
const increment = () => count(count() + 1)
|
|
22
|
+
|
|
23
|
+
return html`
|
|
24
|
+
<div>
|
|
25
|
+
<span>${seconds()}</span>
|
|
26
|
+
</div>
|
|
27
|
+
<div>
|
|
28
|
+
<span>${count()}</span>
|
|
29
|
+
<button @click="${increment}">+</button>
|
|
30
|
+
</div>
|
|
31
|
+
`
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const styles = css`
|
|
35
|
+
:host {
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
text-align: center;
|
|
40
|
+
}
|
|
41
|
+
`
|
|
42
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
import {css, html} from "lit"
|
|
3
|
+
import {CounterView} from "./counter.js"
|
|
4
|
+
import {LoadersView} from "./loaders.js"
|
|
5
|
+
import {view} from "../../features/views/view.js"
|
|
6
|
+
import {cssReset} from "../../features/views/css-reset.js"
|
|
7
|
+
|
|
8
|
+
export const DemoView = view(use => () => {
|
|
9
|
+
use.name("demo")
|
|
10
|
+
use.styles(cssReset, styles)
|
|
11
|
+
|
|
12
|
+
return html`
|
|
13
|
+
${CounterView()}
|
|
14
|
+
${LoadersView()}
|
|
15
|
+
`
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const styles = css`
|
|
19
|
+
:host {
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
gap: 1em;
|
|
23
|
+
}
|
|
24
|
+
`
|
|
25
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
import {css, html} from "lit"
|
|
3
|
+
import {Op} from "../../features/op/op.js"
|
|
4
|
+
import {view} from "../../features/views/view.js"
|
|
5
|
+
import {cssReset} from "../../features/views/css-reset.js"
|
|
6
|
+
import {anims, makeLoader} from "../../features/op/loaders/make-loader.js"
|
|
7
|
+
|
|
8
|
+
export const LoadersView = view(use => () => {
|
|
9
|
+
use.name("loaders")
|
|
10
|
+
use.styles(cssReset, styles)
|
|
11
|
+
|
|
12
|
+
const op = use.once(() => Op.loading())
|
|
13
|
+
|
|
14
|
+
const loaders = use.once(() =>
|
|
15
|
+
Object.entries(anims).map(([key, anim]) => ({
|
|
16
|
+
key,
|
|
17
|
+
loader: makeLoader(anim)
|
|
18
|
+
}))
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
return loaders.map(({key, loader}) => html`
|
|
22
|
+
<div data-anim="${key}">
|
|
23
|
+
<span>${key}</span>
|
|
24
|
+
<span>${loader(op, () => null)}</span>
|
|
25
|
+
</div>
|
|
26
|
+
`)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const styles = css`
|
|
30
|
+
:host {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: row;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
flex-wrap: wrap;
|
|
35
|
+
|
|
36
|
+
gap: 0.2em;
|
|
37
|
+
padding: 1em;
|
|
38
|
+
|
|
39
|
+
width: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
div {
|
|
43
|
+
font-family: monospace;
|
|
44
|
+
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: 0.4em;
|
|
49
|
+
|
|
50
|
+
padding: 0.2em 0.5em;
|
|
51
|
+
background: var(--pill);
|
|
52
|
+
border-radius: 0.5em;
|
|
53
|
+
|
|
54
|
+
span:nth-child(1) { font-size: 0.6em; }
|
|
55
|
+
span:nth-child(2) { font-size: 1.2em; }
|
|
56
|
+
}
|
|
57
|
+
`
|
|
58
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
import {Op} from "../op.js"
|
|
3
|
+
import {braille} from "./parts/anims.js"
|
|
4
|
+
import {Content} from "../../views/types.js"
|
|
5
|
+
import {ErrorDisplay} from "./parts/error-display.js"
|
|
6
|
+
|
|
7
|
+
export * as anims from "./parts/anims.js"
|
|
8
|
+
|
|
9
|
+
export type Loader = <V>(op: Op<V>, ready: (value: V) => Content) => Content
|
|
10
|
+
|
|
11
|
+
export function makeLoader(
|
|
12
|
+
loading: () => Content = braille,
|
|
13
|
+
error: (error: any) => Content = (error: any) => ErrorDisplay(error),
|
|
14
|
+
): Loader {
|
|
15
|
+
|
|
16
|
+
return (op, ready) => op.select({loading, ready, error})
|
|
17
|
+
}
|
|
18
|
+
|