@e280/sly 0.3.0-1 โ 0.3.0-3
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 +66 -60
- package/package.json +1 -1
- package/s/demo/demo.bundle.ts +1 -1
- package/s/dom/dom.ts +1 -1
- package/s/view/shadow.ts +1 -1
- package/x/demo/demo.bundle.js +1 -1
- package/x/demo/demo.bundle.js.map +1 -1
- package/x/demo/demo.bundle.min.js +1 -1
- package/x/demo/demo.bundle.min.js.map +2 -2
- package/x/dom/dom.d.ts +1 -1
- package/x/dom/dom.js.map +1 -1
- package/x/index.html +2 -2
- package/x/view/shadow.d.ts +0 -1
- package/x/view/shadow.js +1 -1
- package/x/view/shadow.js.map +1 -1
package/README.md
CHANGED
|
@@ -2,33 +2,34 @@
|
|
|
2
2
|
<div align="center"><img alt="" width="256" src="./assets/favicon.png"/></div>
|
|
3
3
|
|
|
4
4
|
# ๐ฆ sly
|
|
5
|
-
> *mischievous shadow views*
|
|
6
5
|
|
|
7
6
|
```sh
|
|
8
7
|
npm install lit @e280/sly @e280/strata @e280/stz
|
|
9
8
|
```
|
|
10
9
|
|
|
11
|
-
[@e280](https://e280.org/)'s
|
|
10
|
+
#### [@e280](https://e280.org/)'s [lit-based](https://lit.dev/) web library for reactive light or shadow views
|
|
12
11
|
|
|
13
|
-
-
|
|
14
|
-
- ๐ช [**#hooks
|
|
15
|
-
- ๐ซ [**#ops
|
|
16
|
-
- โณ [**#loaders
|
|
17
|
-
- ๐ช [**#loot
|
|
18
|
-
- ๐ช [**#dom
|
|
19
|
-
- ๐งช https://sly.e280.org
|
|
12
|
+
- ๐ญ [**#views,**](#views) reactive lit views, light-dom or shadow-dom
|
|
13
|
+
- ๐ช [**#hooks,**](#hooks) react-like composable hooks
|
|
14
|
+
- ๐ซ [**#ops,**](#ops) tooling for async operations ui
|
|
15
|
+
- โณ [**#loaders,**](#loaders) render ops with animated loading spinners
|
|
16
|
+
- ๐ช [**#loot,**](#loot) drag-and-drop facilities
|
|
17
|
+
- ๐ช [**#dom,**](#dom) the "it's not jquery" multitool
|
|
18
|
+
- ๐งช **https://sly.e280.org/** sly's testing page
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
<br/><br/>
|
|
24
23
|
<a id="views"></a>
|
|
25
24
|
|
|
26
|
-
##
|
|
27
|
-
> *
|
|
25
|
+
## ๐ญ views
|
|
26
|
+
> *"flourish in the light.. or thrive in the darkness"*
|
|
28
27
|
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
28
|
+
- ๐ **light or shadow,** render nakedly on the page, or within a cozy shadow bubble
|
|
29
|
+
- ๐ช **hooks-based,** familiar react-style [hooks](#hooks)
|
|
30
|
+
- โก **auto-reactive,** views magically rerender on [strata](https://github.com/e280/strata)-compatible state changes
|
|
31
|
+
- ๐ชถ **no compile step,** just god's honest javascript via [lit](https://lit.dev/)-html tagged-template-literals
|
|
32
|
+
- ๐งฉ **not web components,** no dom registration needed, just vibes and good typings
|
|
32
33
|
|
|
33
34
|
```ts
|
|
34
35
|
import {html} from "lit"
|
|
@@ -40,7 +41,7 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
|
|
|
40
41
|
```
|
|
41
42
|
|
|
42
43
|
### ๐ light views
|
|
43
|
-
> *just pretend it's react*
|
|
44
|
+
> *"just pretend it's react, without jsx"*
|
|
44
45
|
|
|
45
46
|
- **define a light view**
|
|
46
47
|
```ts
|
|
@@ -58,14 +59,15 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
|
|
|
58
59
|
```
|
|
59
60
|
- **render it into the dom**
|
|
60
61
|
```ts
|
|
61
|
-
dom.
|
|
62
|
+
dom.render(dom(".demo"), html`
|
|
62
63
|
<h1>my cool counter demo</h1>
|
|
63
64
|
${MyCounter(123)}
|
|
64
65
|
`)
|
|
65
66
|
```
|
|
67
|
+
- **light views are naked,** they don't have a containing host element
|
|
66
68
|
|
|
67
69
|
### ๐ shadow views
|
|
68
|
-
> *each shadow view gets its own cozy [shadow-dom](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) bubble and supports [
|
|
70
|
+
> *each shadow view gets its own cozy [shadow-dom](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) bubble and supports [slotting](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)*
|
|
69
71
|
|
|
70
72
|
- **define a shadow view**
|
|
71
73
|
```ts
|
|
@@ -80,21 +82,21 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
|
|
|
80
82
|
const increment = () => $count.value++
|
|
81
83
|
|
|
82
84
|
return html`
|
|
83
|
-
<button @click="${increment}">${$count
|
|
85
|
+
<button @click="${increment}">${$count.value}</button>
|
|
84
86
|
<slot></slot>
|
|
85
87
|
`
|
|
86
88
|
})
|
|
87
89
|
```
|
|
88
90
|
- **render it into the dom**
|
|
89
91
|
```ts
|
|
90
|
-
dom.
|
|
92
|
+
dom.render(dom(".demo"), html`
|
|
91
93
|
<h1>my cool counter demo</h1>
|
|
92
94
|
${MyShadowCounter(234)}
|
|
93
95
|
`)
|
|
94
96
|
```
|
|
95
97
|
- **.with to nest children or set attrs**
|
|
96
98
|
```ts
|
|
97
|
-
dom.
|
|
99
|
+
dom.render(dom(".demo"), html`
|
|
98
100
|
<h1>my cool counter demo</h1>
|
|
99
101
|
|
|
100
102
|
${MyShadowCounter.with({
|
|
@@ -106,14 +108,17 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
|
|
|
106
108
|
})}
|
|
107
109
|
`)
|
|
108
110
|
```
|
|
109
|
-
- **
|
|
111
|
+
- **you can do custom shadow config if needed**
|
|
110
112
|
```ts
|
|
111
|
-
const
|
|
113
|
+
const customShadow = shadow.config(() => {
|
|
112
114
|
const host = document.createElement("div")
|
|
113
115
|
const shadow = host.attachShadow({mode: "open"})
|
|
114
116
|
return {host, shadow}
|
|
115
|
-
})
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const MyShadowView = customShadow(() => html`<p>shrouded in darkness</p>`)
|
|
116
120
|
```
|
|
121
|
+
- **shadow views are rendered inside** a `<sly-shadow>` host element by default
|
|
117
122
|
|
|
118
123
|
|
|
119
124
|
|
|
@@ -121,48 +126,48 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
|
|
|
121
126
|
<a id="hooks"></a>
|
|
122
127
|
|
|
123
128
|
## ๐ช hooks
|
|
124
|
-
> *composable view state and utilities*
|
|
129
|
+
> *composable view state and utilities*
|
|
125
130
|
|
|
126
131
|
### ๐ฎ follow the hooks rules
|
|
127
132
|
|
|
128
|
-
just like [react hooks](https://react.dev/warnings/invalid-hook-call-warning), the execution order of
|
|
133
|
+
just like [react hooks](https://react.dev/warnings/invalid-hook-call-warning), the execution order of hooks seriously matters.
|
|
129
134
|
|
|
130
|
-
you must not call these hooks under
|
|
135
|
+
you must not call these hooks under if-conditionals, or for-loops, or inside callback functions, or after a conditional return statement, or anything like that.. *otherwise, heed my warning: weird bad stuff will happen..*
|
|
131
136
|
|
|
132
137
|
### ๐ shadow-only hooks
|
|
133
|
-
- **useName
|
|
138
|
+
- **useName,** set the "view" attribute value
|
|
134
139
|
```ts
|
|
135
140
|
useName("squarepants")
|
|
136
141
|
// <sly-shadow view="squarepants">
|
|
137
142
|
```
|
|
138
|
-
- **useCss
|
|
143
|
+
- **useCss,** attach stylesheets (use lit's `css`!) to the shadow root
|
|
139
144
|
```ts
|
|
140
145
|
useCss(css1, css2, css3)
|
|
141
146
|
```
|
|
142
|
-
- **useHost
|
|
147
|
+
- **useHost,** get the host element
|
|
143
148
|
```ts
|
|
144
149
|
const host = useHost()
|
|
145
150
|
```
|
|
146
|
-
- **useShadow
|
|
151
|
+
- **useShadow,** get the shadow root
|
|
147
152
|
```ts
|
|
148
153
|
const shadow = useShadow()
|
|
149
154
|
```
|
|
150
155
|
|
|
151
156
|
### ๐ universal hooks
|
|
152
|
-
- **useState
|
|
157
|
+
- **useState,** react-like hook to create some reactive state (we prefer signals)
|
|
153
158
|
```ts
|
|
154
159
|
const [count, setCount] = useState(0)
|
|
155
160
|
|
|
156
161
|
const increment = () => setCount(n => n + 1)
|
|
157
162
|
```
|
|
158
|
-
- **useRef
|
|
163
|
+
- **useRef,** react-like hook to make a non-reactive box for a value
|
|
159
164
|
```ts
|
|
160
165
|
const ref = useRef(0)
|
|
161
166
|
|
|
162
167
|
ref.current // 0
|
|
163
168
|
ref.current = 1 // does not trigger rerender
|
|
164
169
|
```
|
|
165
|
-
- **useSignal
|
|
170
|
+
- **useSignal,** create a [strata](https://github.com/e280/strata) signal
|
|
166
171
|
```ts
|
|
167
172
|
const $count = useSignal(1)
|
|
168
173
|
|
|
@@ -173,12 +178,12 @@ you must not call these hooks under `if` conditionals, or `for` loops, or in cal
|
|
|
173
178
|
$count(2)
|
|
174
179
|
```
|
|
175
180
|
- see [strata readme](https://github.com/e280/strata)
|
|
176
|
-
- **useDerived
|
|
181
|
+
- **useDerived,** create a [strata](https://github.com/e280/strata) derived signal
|
|
177
182
|
```ts
|
|
178
183
|
const $product = useDerived(() => $count() * $whatever())
|
|
179
184
|
```
|
|
180
185
|
- see [strata readme](https://github.com/e280/strata)
|
|
181
|
-
- **useOnce
|
|
186
|
+
- **useOnce,** run fn at initialization, and return a value
|
|
182
187
|
```ts
|
|
183
188
|
const whatever = useOnce(() => {
|
|
184
189
|
console.log("happens one time")
|
|
@@ -187,14 +192,14 @@ you must not call these hooks under `if` conditionals, or `for` loops, or in cal
|
|
|
187
192
|
|
|
188
193
|
whatever // 123
|
|
189
194
|
```
|
|
190
|
-
- **useMount
|
|
195
|
+
- **useMount,** setup mount/unmount lifecycle
|
|
191
196
|
```ts
|
|
192
197
|
useMount(() => {
|
|
193
198
|
console.log("mounted")
|
|
194
199
|
return () => console.log("unmounted")
|
|
195
200
|
})
|
|
196
201
|
```
|
|
197
|
-
- **useWake
|
|
202
|
+
- **useWake,** run fn each time mounted, and return value
|
|
198
203
|
```ts
|
|
199
204
|
const whatever = useWake(() => {
|
|
200
205
|
console.log("mounted")
|
|
@@ -203,7 +208,7 @@ you must not call these hooks under `if` conditionals, or `for` loops, or in cal
|
|
|
203
208
|
|
|
204
209
|
whatever // 123
|
|
205
210
|
```
|
|
206
|
-
- **useLife
|
|
211
|
+
- **useLife,** mount/unmount lifecycle, but also return a value
|
|
207
212
|
```ts
|
|
208
213
|
const whatever = useLife(() => {
|
|
209
214
|
console.log("mounted")
|
|
@@ -213,30 +218,30 @@ you must not call these hooks under `if` conditionals, or `for` loops, or in cal
|
|
|
213
218
|
|
|
214
219
|
whatever // 123
|
|
215
220
|
```
|
|
216
|
-
- **useRender
|
|
221
|
+
- **useRender,** returns a fn to rerender the view (debounced)
|
|
217
222
|
```ts
|
|
218
223
|
const render = useRender()
|
|
219
224
|
|
|
220
225
|
render().then(() => console.log("render done"))
|
|
221
226
|
```
|
|
222
|
-
- **useRendered
|
|
227
|
+
- **useRendered,** get a promise that resolves *after* the next render
|
|
223
228
|
```ts
|
|
224
229
|
useRendered().then(() => console.log("rendered"))
|
|
225
230
|
```
|
|
226
|
-
- **useOp
|
|
231
|
+
- **useOp,** start loading an op based on an async fn
|
|
227
232
|
```ts
|
|
228
233
|
const op = useOp(async() => {
|
|
229
234
|
await nap(5000)
|
|
230
235
|
return 123
|
|
231
236
|
})
|
|
232
237
|
```
|
|
233
|
-
- **useOpPromise
|
|
238
|
+
- **useOpPromise,** start loading an op based on a promise
|
|
234
239
|
```ts
|
|
235
240
|
const op = useOpPromise(doAsyncWork())
|
|
236
241
|
```
|
|
237
242
|
|
|
238
243
|
### ๐งโ๐ณ happy hooks recipes
|
|
239
|
-
- make a ticker
|
|
244
|
+
- make a ticker, mount, cycle, and nap
|
|
240
245
|
```ts
|
|
241
246
|
import {cycle, nap} from "@e280/stz"
|
|
242
247
|
```
|
|
@@ -250,7 +255,9 @@ you must not call these hooks under `if` conditionals, or `for` loops, or in cal
|
|
|
250
255
|
```
|
|
251
256
|
- wake + rendered, to do something after each mount's first render
|
|
252
257
|
```ts
|
|
253
|
-
|
|
258
|
+
const rendered = useRendered()
|
|
259
|
+
|
|
260
|
+
useWake(() => rendered.then(() => {
|
|
254
261
|
console.log("after first render")
|
|
255
262
|
}))
|
|
256
263
|
```
|
|
@@ -261,7 +268,7 @@ you must not call these hooks under `if` conditionals, or `for` loops, or in cal
|
|
|
261
268
|
<a id="ops"></a>
|
|
262
269
|
|
|
263
270
|
## ๐ซ ops
|
|
264
|
-
> *
|
|
271
|
+
> *helpers for async operations*
|
|
265
272
|
|
|
266
273
|
```ts
|
|
267
274
|
import {nap} from "@e280/stz"
|
|
@@ -299,19 +306,19 @@ import {Pod, podium, Op, loaders} from "@e280/sly"
|
|
|
299
306
|
- see more at [podium.ts](./s/ops/podium.ts)
|
|
300
307
|
|
|
301
308
|
### ๐ซ ops: nice pod ergonomics
|
|
302
|
-
- an `Op<V>` wraps a pod with a signal for reactivity
|
|
309
|
+
- an `Op<V>` wraps a pod with a strata signal for reactivity
|
|
303
310
|
- create an op
|
|
304
311
|
```ts
|
|
305
|
-
|
|
312
|
+
new Op<number>() // loading status by default
|
|
306
313
|
```
|
|
307
314
|
```ts
|
|
308
|
-
|
|
315
|
+
Op.loading<number>()
|
|
309
316
|
```
|
|
310
317
|
```ts
|
|
311
|
-
|
|
318
|
+
Op.ready<number>(123)
|
|
312
319
|
```
|
|
313
320
|
```ts
|
|
314
|
-
|
|
321
|
+
Op.error<number>(new Error())
|
|
315
322
|
```
|
|
316
323
|
- ๐ฅ create an op that calls and tracks an async fn
|
|
317
324
|
```ts
|
|
@@ -338,13 +345,12 @@ import {Pod, podium, Op, loaders} from "@e280/sly"
|
|
|
338
345
|
- select executes a fn based on the status
|
|
339
346
|
```ts
|
|
340
347
|
const result = op.select({
|
|
341
|
-
loading: () => "
|
|
348
|
+
loading: () => "still loading...",
|
|
342
349
|
ready: value => `dude, it's ready! ${value}`,
|
|
343
|
-
error: err => `
|
|
350
|
+
error: err => `ack! an error!`,
|
|
344
351
|
})
|
|
345
352
|
|
|
346
|
-
result
|
|
347
|
-
// "dude, it's ready! 123"
|
|
353
|
+
result // "dude, it's ready! 123"
|
|
348
354
|
```
|
|
349
355
|
- morph returns a new pod, transforming the value if ready
|
|
350
356
|
```ts
|
|
@@ -370,7 +376,7 @@ import {Pod, podium, Op, loaders} from "@e280/sly"
|
|
|
370
376
|
<a id="loaders"></a>
|
|
371
377
|
|
|
372
378
|
## โณ loaders
|
|
373
|
-
> *animated loading spinners for ops*
|
|
379
|
+
> *animated loading spinners for ops*
|
|
374
380
|
|
|
375
381
|
```ts
|
|
376
382
|
import {loaders} from "@e280/sly"
|
|
@@ -527,7 +533,7 @@ import {ev} from "@e280/stz"
|
|
|
527
533
|
<a id="dom"></a>
|
|
528
534
|
|
|
529
535
|
## ๐ช dom
|
|
530
|
-
> *the "it's not jquery!" multitool*
|
|
536
|
+
> *the "it's not jquery!" multitool*
|
|
531
537
|
|
|
532
538
|
```ts
|
|
533
539
|
import {dom} from "@e280/sly"
|
|
@@ -661,10 +667,10 @@ import {dom} from "@e280/sly"
|
|
|
661
667
|
```
|
|
662
668
|
or if you wanna be more loosey-goosey, skip the spec
|
|
663
669
|
```ts
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
670
|
+
const {attrs} = dom.in(".demo")
|
|
671
|
+
attrs.strings.name = "pimsley"
|
|
672
|
+
attrs.numbers.count = 125
|
|
673
|
+
attrs.booleans.active = true
|
|
668
674
|
```
|
|
669
675
|
|
|
670
676
|
|
package/package.json
CHANGED
package/s/demo/demo.bundle.ts
CHANGED
package/s/dom/dom.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {register} from "./parts/register.js"
|
|
|
11
11
|
import {Queryable, Renderable} from "./types.js"
|
|
12
12
|
import {queryAll, queryMaybe, queryRequire} from "./parts/queries.js"
|
|
13
13
|
|
|
14
|
-
export function dom<E extends
|
|
14
|
+
export function dom<E extends HTMLElement>(selector: string, container: Queryable = document) {
|
|
15
15
|
return queryRequire<E>(selector, container)
|
|
16
16
|
}
|
|
17
17
|
|
package/s/view/shadow.ts
CHANGED
package/x/demo/demo.bundle.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demo.bundle.js","sourceRoot":"","sources":["../../s/demo/demo.bundle.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,IAAI,EAAC,MAAM,iBAAiB,CAAA;AAEpC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"demo.bundle.js","sourceRoot":"","sources":["../../s/demo/demo.bundle.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,IAAI,EAAC,MAAM,iBAAiB,CAAA;AAEpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;AAChC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA"}
|