@e280/sly 0.2.0-8 → 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 +400 -98
- package/package.json +14 -7
- package/s/base/element.ts +76 -0
- package/s/base/index.ts +6 -0
- package/s/{views → base}/use.ts +22 -14
- package/s/base/utils/attr-watcher.ts +22 -0
- package/s/base/utils/reactor.ts +32 -0
- package/s/base/utils/states.ts +49 -0
- package/s/base/utils/use-attrs.ts +36 -0
- package/s/demo/demo.bundle.ts +6 -7
- package/s/demo/views/counter.ts +21 -24
- package/s/demo/views/demo.ts +9 -6
- package/s/demo/views/{incredi.ts → fastcount.ts} +7 -6
- package/s/demo/views/loaders.ts +7 -7
- package/s/dom/attrs/attrs.ts +21 -0
- package/s/dom/attrs/parts/attr-fns.ts +68 -0
- package/s/dom/attrs/parts/attr-proxies.ts +35 -0
- package/s/dom/attrs/parts/attr-spec.ts +29 -0
- package/s/dom/attrs/parts/on-attrs.ts +8 -0
- package/s/dom/dom.ts +23 -60
- 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/{register.ts → parts/register.ts} +2 -10
- package/s/dom/types.ts +50 -0
- package/s/index.html.ts +4 -3
- package/s/index.ts +7 -20
- 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/base/element.js +52 -0
- 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 +13 -8
- package/x/base/use.js.map +1 -0
- package/x/base/utils/apply-styles.js.map +1 -0
- package/x/base/utils/attr-watcher.d.ts +8 -0
- package/x/base/utils/attr-watcher.js +20 -0
- package/x/base/utils/attr-watcher.js.map +1 -0
- package/x/base/utils/mounts.js.map +1 -0
- package/x/base/utils/reactor.d.ts +5 -0
- package/x/base/utils/reactor.js +25 -0
- 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 -6
- package/x/demo/demo.bundle.js.map +1 -1
- package/x/demo/demo.bundle.min.js +17 -23
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/demo/views/counter.d.ts +374 -1
- package/x/demo/views/counter.js +19 -22
- 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 -5
- 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} +6 -6
- 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 +23 -0
- package/x/dom/attrs/attrs.js +17 -0
- package/x/dom/attrs/attrs.js.map +1 -0
- package/x/dom/attrs/parts/attr-fns.d.ts +16 -0
- package/x/dom/attrs/parts/attr-fns.js +64 -0
- package/x/dom/attrs/parts/attr-fns.js.map +1 -0
- package/x/dom/attrs/parts/attr-proxies.d.ts +8 -0
- package/x/dom/attrs/parts/attr-proxies.js +21 -0
- package/x/dom/attrs/parts/attr-proxies.js.map +1 -0
- package/x/dom/attrs/parts/attr-spec.d.ts +3 -0
- package/x/dom/attrs/parts/attr-spec.js +21 -0
- package/x/dom/attrs/parts/attr-spec.js.map +1 -0
- package/x/dom/attrs/parts/on-attrs.d.ts +2 -0
- package/x/dom/attrs/parts/on-attrs.js +7 -0
- package/x/dom/attrs/parts/on-attrs.js.map +1 -0
- package/x/dom/dom.d.ts +16 -22
- package/x/dom/dom.js +21 -47
- 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/dashify.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/{register.d.ts → parts/register.d.ts} +2 -10
- package/x/dom/parts/register.js.map +1 -0
- package/x/dom/types.d.ts +22 -0
- package/x/{views → dom}/types.js.map +1 -1
- package/x/index.d.ts +7 -17
- package/x/index.html +6 -5
- package/x/index.html.js +4 -3
- package/x/index.html.js.map +1 -1
- package/x/index.js +7 -17
- 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 +2 -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/view/types.js.map +1 -0
- 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/dom/attributes.ts +0 -89
- package/s/ops/loaders/make-loader.ts +0 -18
- package/s/views/base-element.ts +0 -84
- package/s/views/types.ts +0 -40
- package/s/views/utils/apply-attrs.ts +0 -33
- package/s/views/view.ts +0 -150
- package/x/demo/views/incredi.js.map +0 -1
- package/x/dom/attributes.d.ts +0 -10
- package/x/dom/attributes.js +0 -46
- package/x/dom/attributes.js.map +0 -1
- package/x/dom/dashify.js.map +0 -1
- package/x/dom/register.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 +0 -62
- 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 -31
- 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/mounts.js.map +0 -1
- package/x/views/view.d.ts +0 -9
- package/x/views/view.js +0 -116
- 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/mounts.ts +0 -0
- /package/s/dom/{dashify.ts → parts/dashify.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/mounts.d.ts +0 -0
- /package/x/{views → base}/utils/mounts.js +0 -0
- /package/x/dom/{dashify.d.ts → parts/dashify.d.ts} +0 -0
- /package/x/dom/{dashify.js → parts/dashify.js} +0 -0
- /package/x/dom/{register.js → parts/register.js} +0 -0
- /package/x/{views → dom}/types.js +0 -0
- /package/x/{ops/loaders → loaders}/parts/anims.js +0 -0
package/README.md
CHANGED
|
@@ -4,13 +4,16 @@
|
|
|
4
4
|
# 🦝 sly
|
|
5
5
|
> *mischievous shadow views*
|
|
6
6
|
|
|
7
|
-
[@e280](https://e280.org/)'s
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
7
|
+
[@e280](https://e280.org/)'s new [lit](https://lit.dev/)-based frontend webdev library. *(sly replaces its predecessor, [slate](https://github.com/benevolent-games/slate))*
|
|
8
|
+
|
|
9
|
+
- **✨[shiny](https://shiny.e280.org/)✨** — our wip component library https://shiny.e280.org/
|
|
10
|
+
- 🍋 [**#views**](#views) — shadow-dom'd, hooks-based, componentizable
|
|
11
|
+
- 🪵 [**#base-element**](#base-element) — for a more classical experience
|
|
12
|
+
- 🪄 [**#dom**](#dom) — the "it's not jquery" multitool
|
|
13
|
+
- 🫛 [**#ops**](#ops) — reactive tooling for async operations
|
|
14
|
+
- ⏳ [**#loaders**](#loaders) — animated loading spinners for rendering ops
|
|
15
|
+
- 💅 [**#spa**](#spa) — hash routing for your spa-day
|
|
16
|
+
- 🪙 [**#loot**](#loot) — drag-and-drop facilities
|
|
14
17
|
- 🧪 testing page — https://sly.e280.org/
|
|
15
18
|
|
|
16
19
|
|
|
@@ -18,9 +21,10 @@
|
|
|
18
21
|
<br/><br/>
|
|
19
22
|
|
|
20
23
|
## 🦝 sly and friends
|
|
24
|
+
> `@e280/sly`
|
|
21
25
|
|
|
22
26
|
```sh
|
|
23
|
-
npm install @e280/sly lit
|
|
27
|
+
npm install @e280/sly lit @e280/strata @e280/stz
|
|
24
28
|
```
|
|
25
29
|
|
|
26
30
|
> [!NOTE]
|
|
@@ -29,75 +33,87 @@ npm install @e280/sly lit
|
|
|
29
33
|
> - 🏂 [@e280/stz](https://github.com/e280/stz), our ts standard library
|
|
30
34
|
> - 🐢 [@e280/scute](https://github.com/e280/scute), our buildy-bundly-buddy
|
|
31
35
|
|
|
36
|
+
> [!TIP]
|
|
37
|
+
> you can import everything in sly from `@e280/sly`,
|
|
38
|
+
> or from specific subpackages like `@e280/sly/view`, `@e280/sly/dom`, etc...
|
|
39
|
+
|
|
32
40
|
|
|
33
41
|
|
|
34
42
|
<br/><br/>
|
|
35
43
|
<a id="views"></a>
|
|
36
44
|
|
|
37
|
-
##
|
|
38
|
-
>
|
|
45
|
+
## 🍋🦝 sly views
|
|
46
|
+
> `@e280/sly/view`
|
|
47
|
+
> *the crown jewel of sly*
|
|
39
48
|
|
|
40
49
|
```ts
|
|
41
50
|
view(use => () => html`<p>hello world</p>`)
|
|
42
51
|
```
|
|
43
52
|
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
53
|
+
- 🪶 **no compile step** — just god's honest javascript, via [lit](https://lit.dev/)-html tagged-template-literals
|
|
54
|
+
- 🥷 **shadow dom'd** — each view gets its own cozy [shadow](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) bubble, and supports [slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)
|
|
55
|
+
- 🪝 **hooks-based** — declarative rendering with the [`use`](#use) family of ergonomic hooks
|
|
56
|
+
- ⚡ **reactive** — they auto-rerender whenever any [strata](https://github.com/e280/strata)-compatible state changes
|
|
57
|
+
- 🧐 **not components, per se** — they're comfy typescript-native ui building blocks [(technically, lit directives)](https://lit.dev/docs/templates/custom-directives/)
|
|
58
|
+
- 🧩 **componentizable** — any view can be magically converted into a proper [web component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
|
|
48
59
|
|
|
49
60
|
### 🍋 view example
|
|
50
61
|
```ts
|
|
51
|
-
import {view, dom} from "@e280/sly"
|
|
62
|
+
import {view, dom, BaseElement} from "@e280/sly"
|
|
52
63
|
import {html, css} from "lit"
|
|
53
64
|
```
|
|
54
|
-
- **declare
|
|
65
|
+
- **declare view**
|
|
55
66
|
```ts
|
|
56
67
|
export const CounterView = view(use => (start: number) => {
|
|
57
|
-
use.name("counter")
|
|
58
68
|
use.styles(css`p {color: green}`)
|
|
59
69
|
|
|
60
70
|
const $count = use.signal(start)
|
|
61
71
|
const increment = () => $count.value++
|
|
62
72
|
|
|
63
73
|
return html`
|
|
64
|
-
<
|
|
65
|
-
|
|
74
|
+
<button @click="${increment}">
|
|
75
|
+
${$count.value}
|
|
76
|
+
</button>
|
|
66
77
|
`
|
|
67
78
|
})
|
|
68
79
|
```
|
|
69
|
-
-
|
|
70
|
-
- **inject
|
|
80
|
+
- `$count` is a [strata signal](https://github.com/e280/strata#readme) *(we like those)*
|
|
81
|
+
- **inject view into dom**
|
|
71
82
|
```ts
|
|
72
83
|
dom.in(".app").render(html`
|
|
73
84
|
<h1>cool counter demo</h1>
|
|
74
85
|
${CounterView(1)}
|
|
75
86
|
`)
|
|
76
87
|
```
|
|
77
|
-
- 🤯 **register
|
|
88
|
+
- 🤯 **register view as web component**
|
|
78
89
|
```ts
|
|
79
|
-
dom.register({
|
|
80
|
-
|
|
90
|
+
dom.register({
|
|
91
|
+
MyCounter: CounterView
|
|
92
|
+
.component()
|
|
93
|
+
.props(() => [1]),
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
```html
|
|
97
|
+
<my-counter></my-counter>
|
|
81
98
|
```
|
|
82
99
|
|
|
83
|
-
### 🍋 view
|
|
84
|
-
-
|
|
100
|
+
### 🍋 view settings
|
|
101
|
+
- optional settings for views you should know about
|
|
85
102
|
```ts
|
|
86
103
|
export const CoolView = view
|
|
87
104
|
.settings({mode: "open", delegatesFocus: true})
|
|
88
|
-
.
|
|
89
|
-
return html`😎 ${greeting} <slot></slot>`
|
|
90
|
-
})
|
|
105
|
+
.render(use => (greeting: string) => html`😎 ${greeting} <slot></slot>`)
|
|
91
106
|
```
|
|
92
107
|
- all [attachShadow params](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#parameters) (like `mode` and `delegatesFocus`) are valid `settings`
|
|
93
108
|
- note the `<slot></slot>` we'll use in the next example lol
|
|
94
109
|
|
|
95
|
-
### 🍋 view
|
|
96
|
-
-
|
|
110
|
+
### 🍋 view chains
|
|
111
|
+
- views have this sick chaining syntax for supplying more stuff at the template injection site
|
|
97
112
|
```ts
|
|
98
113
|
dom.in(".app").render(html`
|
|
99
114
|
<h2>cool example</h2>
|
|
100
|
-
${CoolView
|
|
115
|
+
${CoolView
|
|
116
|
+
.props("hello")
|
|
101
117
|
.attr("class", "hero")
|
|
102
118
|
.children(html`<em>spongebob</em>`)
|
|
103
119
|
.render()}
|
|
@@ -105,30 +121,102 @@ import {html, css} from "lit"
|
|
|
105
121
|
```
|
|
106
122
|
- `props` — provide props and start a view chain
|
|
107
123
|
- `attr` — set html attributes on the `<sly-view>` host element
|
|
108
|
-
- `children` — nested
|
|
124
|
+
- `children` — add nested [slottable](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots) content
|
|
109
125
|
- `render` — end the view chain and render the lit directive
|
|
110
126
|
|
|
111
|
-
### 🍋 view
|
|
112
|
-
- **
|
|
127
|
+
### 🍋 view/component universality
|
|
128
|
+
- **you can start with a view,**
|
|
129
|
+
```ts
|
|
130
|
+
export const GreeterView = view(use => (name: string) => {
|
|
131
|
+
return html`<p>hello ${name}</p>`
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
- view usage
|
|
135
|
+
```ts
|
|
136
|
+
GreeterView("pimsley")
|
|
137
|
+
```
|
|
138
|
+
**then you can convert it to a component.**
|
|
113
139
|
```ts
|
|
114
|
-
|
|
140
|
+
export class GreeterComponent extends (
|
|
141
|
+
GreeterView
|
|
142
|
+
.component()
|
|
143
|
+
.props(component => [component.getAttribute("name") ?? "unknown"])
|
|
144
|
+
) {}
|
|
115
145
|
```
|
|
116
|
-
-
|
|
117
|
-
|
|
146
|
+
- html usage
|
|
147
|
+
```html
|
|
148
|
+
<greeter-component name="pimsley"></greeter-component>
|
|
149
|
+
```
|
|
150
|
+
- **you can start with a component,**
|
|
118
151
|
```ts
|
|
119
|
-
|
|
152
|
+
export class GreeterComponent extends (
|
|
153
|
+
view(use => (name: string) => {
|
|
154
|
+
return html`<p>hello ${name}</p>`
|
|
155
|
+
})
|
|
156
|
+
.component()
|
|
157
|
+
.props(component => [component.getAttribute("name") ?? "unknown"])
|
|
158
|
+
) {}
|
|
120
159
|
```
|
|
121
|
-
-
|
|
122
|
-
|
|
160
|
+
- html usage
|
|
161
|
+
```html
|
|
162
|
+
<greeter-component name="pimsley"></greeter-component>
|
|
163
|
+
```
|
|
164
|
+
**and it already has `.view` ready for you.**
|
|
165
|
+
- view usage
|
|
166
|
+
```ts
|
|
167
|
+
GreeterComponent.view("pimsley")
|
|
168
|
+
```
|
|
169
|
+
- **understanding `.component(BaseElement)` and `.props(fn)`**
|
|
170
|
+
- `.props` takes a fn that is called every render, which returns the props given to the view
|
|
171
|
+
```ts
|
|
172
|
+
.props(() => ["pimsley"])
|
|
173
|
+
```
|
|
174
|
+
the props fn receives the component instance, so you can query html attributes or instance properties
|
|
175
|
+
```ts
|
|
176
|
+
.props(component => [component.getAttribute("name") ?? "unknown"])
|
|
177
|
+
```
|
|
178
|
+
- `.component` accepts a subclass of `BaseElement`, so you can define your own properties and methods for your component class
|
|
179
|
+
```ts
|
|
180
|
+
const GreeterComponent = GreeterView
|
|
181
|
+
|
|
182
|
+
// declare your own custom class
|
|
183
|
+
.component(class extends BaseElement {
|
|
184
|
+
$name = signal("jim raynor")
|
|
185
|
+
updateName(name: string) {
|
|
186
|
+
this.$name.value = name
|
|
187
|
+
}
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// props gets the right types on 'component'
|
|
191
|
+
.props(component => [component.$name.value])
|
|
192
|
+
```
|
|
193
|
+
- `.component` provides the devs interacting with your component, with noice typings
|
|
194
|
+
```ts
|
|
195
|
+
dom<GreeterComponent>("greeter-component").updateName("mortimer")
|
|
196
|
+
```
|
|
197
|
+
- typescript class wizardry
|
|
198
|
+
- ❌ smol-brain approach exports class value, but NOT the typings
|
|
199
|
+
```ts
|
|
200
|
+
export const GreeterComponent = (...)
|
|
201
|
+
```
|
|
202
|
+
- ✅ giga-brain approach exports class value AND the typings
|
|
203
|
+
```ts
|
|
204
|
+
export class GreeterComponent extends (...) {}
|
|
205
|
+
```
|
|
123
206
|
- **register web components to the dom**
|
|
124
207
|
```ts
|
|
125
|
-
dom.register({
|
|
126
|
-
|
|
127
|
-
|
|
208
|
+
dom.register({GreeterComponent})
|
|
209
|
+
```
|
|
210
|
+
- **oh and don't miss out on the insta-component shorthand**
|
|
211
|
+
```ts
|
|
212
|
+
dom.register({
|
|
213
|
+
QuickComponent: view.component(use => html`⚡ incredi`),
|
|
214
|
+
})
|
|
128
215
|
```
|
|
129
|
-
- `dom.register` automatically dashes the tag names (`MyComponent` becomes `<my-component>`)
|
|
130
216
|
|
|
131
|
-
|
|
217
|
+
<a id="use"></a>
|
|
218
|
+
|
|
219
|
+
### 🍋 "use" hooks reference
|
|
132
220
|
- 👮 **follow the hooks rules**
|
|
133
221
|
> just like [react hooks](https://react.dev/warnings/invalid-hook-call-warning), the execution order of sly's `use` hooks actually matters..
|
|
134
222
|
> you must not call these hooks under `if` conditionals, or `for` loops, or in callbacks, or after a conditional `return` statement, or anything like that.. *otherwise, heed my warning: weird bad stuff will happen..*
|
|
@@ -198,20 +286,46 @@ import {html, css} from "lit"
|
|
|
198
286
|
|
|
199
287
|
v // 123
|
|
200
288
|
```
|
|
201
|
-
- **use.
|
|
202
|
-
*(see [dom.attrs](#dom.attrs) for more details)*
|
|
289
|
+
- **use.events** — attach event listeners to the element (auto-cleaned up)
|
|
203
290
|
```ts
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
active: Boolean,
|
|
291
|
+
use.events({
|
|
292
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
293
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
208
294
|
})
|
|
209
295
|
```
|
|
296
|
+
- **use.states** — [internal states](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states) helper
|
|
210
297
|
```ts
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
attrs.active // true
|
|
298
|
+
const states = use.states()
|
|
299
|
+
states.assign("active", "cool")
|
|
214
300
|
```
|
|
301
|
+
```css
|
|
302
|
+
[view="my-view"]::state(active) { color: yellow; }
|
|
303
|
+
[view="my-view"]::state(cool) { outline: 1px solid cyan; }
|
|
304
|
+
```
|
|
305
|
+
- **use.attrs** — ergonomic typed html attribute access
|
|
306
|
+
- `use.attrs` is similar to [#dom.attrs](#dom.attrs)
|
|
307
|
+
```ts
|
|
308
|
+
const attrs = use.attrs({
|
|
309
|
+
name: String,
|
|
310
|
+
count: Number,
|
|
311
|
+
active: Boolean,
|
|
312
|
+
})
|
|
313
|
+
```
|
|
314
|
+
```ts
|
|
315
|
+
attrs.name // "chase"
|
|
316
|
+
attrs.count // 123
|
|
317
|
+
attrs.active // true
|
|
318
|
+
```
|
|
319
|
+
- use.attrs.{strings/numbers/booleans}
|
|
320
|
+
```ts
|
|
321
|
+
use.attrs.strings.name // "chase"
|
|
322
|
+
use.attrs.numbers.count // 123
|
|
323
|
+
use.attrs.booleans.active // true
|
|
324
|
+
```
|
|
325
|
+
- use.attrs.on
|
|
326
|
+
```ts
|
|
327
|
+
use.attrs.on(() => console.log("an attribute changed"))
|
|
328
|
+
```
|
|
215
329
|
- **use.render** — rerender the view (debounced)
|
|
216
330
|
```ts
|
|
217
331
|
use.render()
|
|
@@ -239,15 +353,15 @@ import {html, css} from "lit"
|
|
|
239
353
|
const op = use.op.promise(doAsyncWork())
|
|
240
354
|
```
|
|
241
355
|
|
|
242
|
-
### 🍋
|
|
243
|
-
- make a ticker — mount,
|
|
356
|
+
### 🍋 "use" recipes
|
|
357
|
+
- make a ticker — mount, cycle, and nap
|
|
244
358
|
```ts
|
|
245
|
-
import {
|
|
359
|
+
import {cycle, nap} from "@e280/stz"
|
|
246
360
|
```
|
|
247
361
|
```ts
|
|
248
362
|
const $seconds = use.signal(0)
|
|
249
363
|
|
|
250
|
-
use.mount(() =>
|
|
364
|
+
use.mount(() => cycle(async() => {
|
|
251
365
|
await nap(1000)
|
|
252
366
|
$seconds.value++
|
|
253
367
|
}))
|
|
@@ -264,19 +378,36 @@ import {html, css} from "lit"
|
|
|
264
378
|
<br/><br/>
|
|
265
379
|
<a id="base-element"></a>
|
|
266
380
|
|
|
267
|
-
##
|
|
268
|
-
>
|
|
381
|
+
## 🪵🦝 sly base element
|
|
382
|
+
> `@e280/sly/base`
|
|
383
|
+
> *the classic experience*
|
|
269
384
|
|
|
270
385
|
```ts
|
|
271
386
|
import {BaseElement, Use, dom} from "@e280/sly"
|
|
272
387
|
import {html, css} from "lit"
|
|
273
388
|
```
|
|
274
389
|
|
|
275
|
-
`BaseElement` is
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
390
|
+
`BaseElement` is more of an old-timey class-based "boomer" approach to making web components, but with a millennial twist — its `render` method gives you the same `use` hooks that views enjoy.
|
|
391
|
+
|
|
392
|
+
👮 a *BaseElement* is not a *View*, and cannot be converted into a *View*.
|
|
393
|
+
|
|
394
|
+
### 🪵 let's clarify some sly terminology
|
|
395
|
+
- "Element"
|
|
396
|
+
- an html element; any subclass of the browser's HTMLElement
|
|
397
|
+
- all genuine ["web components"](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) are elements
|
|
398
|
+
- "BaseElement"
|
|
399
|
+
- sly's own subclass of the browser-native HTMLElement
|
|
400
|
+
- is a true element and web component (can be registered to the dom)
|
|
401
|
+
- "View"
|
|
402
|
+
- sly's own magic concept that uses a lit-directive to render stuff
|
|
403
|
+
- NOT an element or web component (can NOT be registered to the dom)
|
|
404
|
+
- NOT related to BaseElement
|
|
405
|
+
- can be converted into a Component via `view.component().props(() => [])`
|
|
406
|
+
- "Component"
|
|
407
|
+
- a sly view that has been converted into an element
|
|
408
|
+
- is a true element and web component (can be registered to the dom)
|
|
409
|
+
- actually a subclass of BaseElement
|
|
410
|
+
- actually contains the view on `Component.view`
|
|
280
411
|
|
|
281
412
|
### 🪵 base element setup
|
|
282
413
|
- **declare your element class**
|
|
@@ -285,10 +416,10 @@ base element enjoys the same `use` hooks as views.
|
|
|
285
416
|
static styles = css`span{color:orange}`
|
|
286
417
|
|
|
287
418
|
// custom property
|
|
288
|
-
start = 10
|
|
419
|
+
$start = signal(10)
|
|
289
420
|
|
|
290
421
|
// custom attributes
|
|
291
|
-
attrs = dom.attrs(this
|
|
422
|
+
attrs = dom.attrs(this).spec({
|
|
292
423
|
multiply: Number,
|
|
293
424
|
})
|
|
294
425
|
|
|
@@ -301,9 +432,9 @@ base element enjoys the same `use` hooks as views.
|
|
|
301
432
|
const $count = use.signal(1)
|
|
302
433
|
const increment = () => $count.value++
|
|
303
434
|
|
|
304
|
-
const {start} = this
|
|
435
|
+
const {$start} = this
|
|
305
436
|
const {multiply = 1} = this.attrs
|
|
306
|
-
const result = start + (multiply * $count())
|
|
437
|
+
const result = $start() + (multiply * $count())
|
|
307
438
|
|
|
308
439
|
return html`
|
|
309
440
|
<span>${result}</span>
|
|
@@ -329,7 +460,7 @@ base element enjoys the same `use` hooks as views.
|
|
|
329
460
|
const myElement = dom<MyElement>("my-element")
|
|
330
461
|
|
|
331
462
|
// js property
|
|
332
|
-
myElement
|
|
463
|
+
myElement.$start(100)
|
|
333
464
|
|
|
334
465
|
// html attributes
|
|
335
466
|
myElement.attrs.multiply = 2
|
|
@@ -344,8 +475,9 @@ base element enjoys the same `use` hooks as views.
|
|
|
344
475
|
<br/><br/>
|
|
345
476
|
<a id="dom"></a>
|
|
346
477
|
|
|
347
|
-
##
|
|
348
|
-
>
|
|
478
|
+
## 🪄🦝 sly dom
|
|
479
|
+
> `@e280/sly/dom`
|
|
480
|
+
> *the "it's not jquery!" multitool*
|
|
349
481
|
|
|
350
482
|
```ts
|
|
351
483
|
import {dom} from "@e280/sly"
|
|
@@ -357,50 +489,107 @@ import {dom} from "@e280/sly"
|
|
|
357
489
|
dom(".demo")
|
|
358
490
|
// HTMLElement (or throws)
|
|
359
491
|
```
|
|
492
|
+
```ts
|
|
493
|
+
// alias
|
|
494
|
+
dom.require(".demo")
|
|
495
|
+
// HTMLElement (or throws)
|
|
496
|
+
```
|
|
360
497
|
- `maybe` get an element
|
|
361
498
|
```ts
|
|
362
499
|
dom.maybe(".demo")
|
|
363
500
|
// HTMLElement | undefined
|
|
364
501
|
```
|
|
365
|
-
- `
|
|
502
|
+
- `all` matching elements in an array
|
|
366
503
|
```ts
|
|
367
504
|
dom.all(".demo ul li")
|
|
368
505
|
// HTMLElement[]
|
|
369
506
|
```
|
|
370
|
-
|
|
507
|
+
|
|
508
|
+
### 🪄 dom.in scope
|
|
509
|
+
- make a scope
|
|
371
510
|
```ts
|
|
372
|
-
dom
|
|
373
|
-
//
|
|
511
|
+
dom.in(".demo") // selector
|
|
512
|
+
// Dom instance
|
|
374
513
|
```
|
|
375
514
|
```ts
|
|
376
|
-
dom
|
|
377
|
-
//
|
|
515
|
+
dom.in(demoElement) // element
|
|
516
|
+
// Dom instance
|
|
378
517
|
```
|
|
518
|
+
- run queries in that scope
|
|
379
519
|
```ts
|
|
380
|
-
dom(
|
|
381
|
-
|
|
520
|
+
dom.in(demoElement).require(".button")
|
|
521
|
+
```
|
|
522
|
+
```ts
|
|
523
|
+
dom.in(demoElement).maybe(".button")
|
|
524
|
+
```
|
|
525
|
+
```ts
|
|
526
|
+
dom.in(demoElement).all("ol li")
|
|
382
527
|
```
|
|
383
528
|
|
|
384
529
|
### 🪄 dom utilities
|
|
385
|
-
- `register` web components
|
|
530
|
+
- `dom.register` web components
|
|
386
531
|
```ts
|
|
387
532
|
dom.register({MyComponent, AnotherCoolComponent})
|
|
388
533
|
// <my-component>
|
|
389
534
|
// <another-cool-component>
|
|
390
535
|
```
|
|
391
|
-
- `
|
|
536
|
+
- `dom.register` automatically dashes the tag names (`MyComponent` becomes `<my-component>`)
|
|
537
|
+
- `dom.render` content into an element
|
|
392
538
|
```ts
|
|
393
|
-
dom
|
|
539
|
+
dom.render(element, html`<p>hello world</p>`)
|
|
394
540
|
```
|
|
395
541
|
```ts
|
|
396
542
|
dom.in(".demo").render(html`<p>hello world</p>`)
|
|
397
543
|
```
|
|
544
|
+
- `dom.el` little element builder
|
|
398
545
|
```ts
|
|
399
|
-
dom.
|
|
546
|
+
const div = dom.el("div", {"data-whatever": 123, "data-active": true})
|
|
547
|
+
// <div data-whatever="123" data-active></div>
|
|
400
548
|
```
|
|
401
|
-
- `
|
|
549
|
+
- `dom.elmer` make an element with a fluent chain
|
|
402
550
|
```ts
|
|
403
|
-
const
|
|
551
|
+
const div = dom.elmer("div")
|
|
552
|
+
.attr("data-whatever", 123)
|
|
553
|
+
.attr("data-active")
|
|
554
|
+
.children("hello world")
|
|
555
|
+
.done()
|
|
556
|
+
// HTMLElement
|
|
557
|
+
```
|
|
558
|
+
- `dom.mk` make an element with a lit template (returns the first)
|
|
559
|
+
```ts
|
|
560
|
+
const div = dom.mk(html`
|
|
561
|
+
<div data-whatever="123" data-active>
|
|
562
|
+
hello world
|
|
563
|
+
</div>
|
|
564
|
+
`) // HTMLElement
|
|
565
|
+
```
|
|
566
|
+
- `dom.events` <a id="dom.events"></a> to attach event listeners
|
|
567
|
+
```ts
|
|
568
|
+
const detach = dom.events(element, {
|
|
569
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
570
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
571
|
+
})
|
|
572
|
+
```
|
|
573
|
+
```ts
|
|
574
|
+
const detach = dom.in(".demo").events({
|
|
575
|
+
keydown: (e: KeyboardEvent) => console.log("keydown", e.code),
|
|
576
|
+
keyup: (e: KeyboardEvent) => console.log("keyup", e.code),
|
|
577
|
+
})
|
|
578
|
+
```
|
|
579
|
+
```ts
|
|
580
|
+
// unattach those event listeners when you're done
|
|
581
|
+
detach()
|
|
582
|
+
```
|
|
583
|
+
- `dom.attrs` <a id="dom.attrs"></a> to setup a type-happy html attribute helper
|
|
584
|
+
```ts
|
|
585
|
+
const attrs = dom.attrs(element).spec({
|
|
586
|
+
name: String,
|
|
587
|
+
count: Number,
|
|
588
|
+
active: Boolean,
|
|
589
|
+
})
|
|
590
|
+
```
|
|
591
|
+
```ts
|
|
592
|
+
const attrs = dom.in(".demo").attrs.spec({
|
|
404
593
|
name: String,
|
|
405
594
|
count: Number,
|
|
406
595
|
active: Boolean,
|
|
@@ -420,18 +609,26 @@ import {dom} from "@e280/sly"
|
|
|
420
609
|
attrs.name = undefined // removes the attr
|
|
421
610
|
attrs.count = undefined // removes the attr
|
|
422
611
|
```
|
|
612
|
+
or if you wanna be more loosey-goosey, skip the spec
|
|
613
|
+
```ts
|
|
614
|
+
const a = dom.in(".demo").attrs
|
|
615
|
+
a.strings.name = "pimsley"
|
|
616
|
+
a.numbers.count = 125
|
|
617
|
+
a.booleans.active = true
|
|
618
|
+
```
|
|
423
619
|
|
|
424
620
|
|
|
425
621
|
|
|
426
622
|
<br/><br/>
|
|
427
623
|
<a id="ops"></a>
|
|
428
624
|
|
|
429
|
-
##
|
|
430
|
-
>
|
|
625
|
+
## 🫛🦝 sly ops
|
|
626
|
+
> `@e280/sly/ops`
|
|
627
|
+
> *tools for async operations and loading spinners*
|
|
431
628
|
|
|
432
629
|
```ts
|
|
433
630
|
import {nap} from "@e280/stz"
|
|
434
|
-
import {Pod, podium, Op,
|
|
631
|
+
import {Pod, podium, Op, loaders} from "@e280/sly"
|
|
435
632
|
```
|
|
436
633
|
|
|
437
634
|
### 🫛 pods: loading/ready/error
|
|
@@ -530,14 +727,29 @@ import {Pod, podium, Op, makeLoader, anims} from "@e280/sly"
|
|
|
530
727
|
- loading if any ops are in loading, otherwise
|
|
531
728
|
- ready if all the ops are ready
|
|
532
729
|
|
|
533
|
-
|
|
534
|
-
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
<br/><br/>
|
|
733
|
+
<a id="loaders"></a>
|
|
734
|
+
|
|
735
|
+
## ⏳🦝 sly loaders
|
|
736
|
+
> `@e280/sly/loaders`
|
|
737
|
+
> *animated loading spinners for ops*
|
|
738
|
+
|
|
739
|
+
```ts
|
|
740
|
+
import {loaders} from "@e280/sly"
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
### ⏳ make a loader, choose an anim
|
|
744
|
+
- create a loader fn
|
|
535
745
|
```ts
|
|
536
|
-
const loader =
|
|
746
|
+
const loader = loaders.make(loaders.anims.dots)
|
|
537
747
|
```
|
|
538
748
|
- see all the anims available on the testing page https://sly.e280.org/
|
|
539
749
|
- ngl, i made too many.. *i was having fun, okay?*
|
|
540
|
-
|
|
750
|
+
|
|
751
|
+
### ⏳ render an op with it
|
|
752
|
+
- use your loader to render an op
|
|
541
753
|
```ts
|
|
542
754
|
return html`
|
|
543
755
|
<h2>cool stuff</h2>
|
|
@@ -553,11 +765,101 @@ import {Pod, podium, Op, makeLoader, anims} from "@e280/sly"
|
|
|
553
765
|
|
|
554
766
|
|
|
555
767
|
|
|
768
|
+
<br/><br/>
|
|
769
|
+
<a id="spa"></a>
|
|
770
|
+
|
|
771
|
+
## 💅🦝 sly spa
|
|
772
|
+
> `@e280/sly/spa`
|
|
773
|
+
> *hash router for single-page-apps*
|
|
774
|
+
|
|
775
|
+
```ts
|
|
776
|
+
import {spa, html} from "@e280/sly"
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### 💅 spa.Router basics
|
|
780
|
+
- **make a spa router**
|
|
781
|
+
```ts
|
|
782
|
+
const router = new spa.Router({
|
|
783
|
+
routes: {
|
|
784
|
+
home: spa.route("#/", async() => html`home`),
|
|
785
|
+
settings: spa.route("#/settings", async() => html`settings`),
|
|
786
|
+
user: spa.route("#/user/{userId}", async({userId}) => html`user ${userId}`),
|
|
787
|
+
},
|
|
788
|
+
})
|
|
789
|
+
```
|
|
790
|
+
- all route strings must start with `#/`
|
|
791
|
+
- use braces like `{userId}` to accept string params
|
|
792
|
+
- home-equivalent hashes like `""` and `"#"` are normalized to `"#/"`
|
|
793
|
+
- the router has an effect on the appearance of the url in the browser address bar -- the home `#/` is removed, aesthetically, eg, `e280.org/#/` is rewritten to `e280.org` using *history.replaceState*
|
|
794
|
+
- you can provide `loader` option if you want to specify the loading spinner (defaults to `loaders.make()`)
|
|
795
|
+
- you can provide `notFound` option, if you want to specify what is shown on invalid routes (defaults to `() => null`)
|
|
796
|
+
- when `auto` is true (default), the router calls `.refresh()` and `.listen()` in the constructor.. set it to `false` if you want manual control
|
|
797
|
+
- you can set `auto` option false if you want to omit the default initial refresh and listen calls
|
|
798
|
+
- **render your current page**
|
|
799
|
+
```ts
|
|
800
|
+
return html`
|
|
801
|
+
<div class="my-page">
|
|
802
|
+
${router.render()}
|
|
803
|
+
</div>
|
|
804
|
+
`
|
|
805
|
+
```
|
|
806
|
+
- returns lit content
|
|
807
|
+
- shows a loading spinner when pages are loading
|
|
808
|
+
- will display the notFound content for invalid routes (defaults to null)
|
|
809
|
+
- **perform navigations**
|
|
810
|
+
- go to settings page
|
|
811
|
+
```ts
|
|
812
|
+
await router.nav.settings.go()
|
|
813
|
+
// goes to "#/settings"
|
|
814
|
+
```
|
|
815
|
+
- go to user page
|
|
816
|
+
```ts
|
|
817
|
+
await router.nav.user.go("123")
|
|
818
|
+
// goes to "#/user/123"
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
### 💅 spa.Router advanced
|
|
822
|
+
- **generate a route's hash string**
|
|
823
|
+
```ts
|
|
824
|
+
const hash = router.nav.user.hash("123")
|
|
825
|
+
// "#/user/123"
|
|
826
|
+
|
|
827
|
+
html`<a href="${hash}">user 123</a>`
|
|
828
|
+
```
|
|
829
|
+
- **check if a route is the currently-active one**
|
|
830
|
+
```ts
|
|
831
|
+
const hash = router.nav.user.active
|
|
832
|
+
// true
|
|
833
|
+
```
|
|
834
|
+
- **force-refresh the router**
|
|
835
|
+
```ts
|
|
836
|
+
await router.refresh()
|
|
837
|
+
```
|
|
838
|
+
- **force-navigate the router by hash**
|
|
839
|
+
```ts
|
|
840
|
+
await router.refresh("#/user/123")
|
|
841
|
+
```
|
|
842
|
+
- **get the current hash string (normalized)**
|
|
843
|
+
```ts
|
|
844
|
+
router.hash
|
|
845
|
+
// "#/user/123"
|
|
846
|
+
```
|
|
847
|
+
- **the `route(...)` helper fn enables the braces-params syntax**
|
|
848
|
+
- but, if you wanna do it differently, you *can* implement your own hash parser to do your own funky syntax
|
|
849
|
+
- **dispose the router when you're done with it**
|
|
850
|
+
```ts
|
|
851
|
+
router.dispose()
|
|
852
|
+
// stop listening to hashchange events
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
556
857
|
<br/><br/>
|
|
557
858
|
<a id="loot"></a>
|
|
558
859
|
|
|
559
|
-
##
|
|
560
|
-
>
|
|
860
|
+
## 🪙🦝 loot
|
|
861
|
+
> `@e280/sly/loot`
|
|
862
|
+
> *drag-and-drop facilities*
|
|
561
863
|
|
|
562
864
|
```ts
|
|
563
865
|
import {loot, view, dom} from "@e280/sly"
|
|
@@ -599,7 +901,7 @@ import {ev} from "@e280/stz"
|
|
|
599
901
|
})
|
|
600
902
|
|
|
601
903
|
// sly attribute handler for the body
|
|
602
|
-
const attrs = dom.attrs(document.body
|
|
904
|
+
const attrs = dom.attrs(document.body).spec({
|
|
603
905
|
"data-indicator": Boolean,
|
|
604
906
|
})
|
|
605
907
|
|
|
@@ -678,7 +980,7 @@ import {ev} from "@e280/stz"
|
|
|
678
980
|
<br/><br/>
|
|
679
981
|
<a id="e280"></a>
|
|
680
982
|
|
|
681
|
-
##
|
|
983
|
+
## 🧑💻🦝 sly is by e280
|
|
682
984
|
reward us with github stars
|
|
683
985
|
build with us at https://e280.org/ but only if you're cool
|
|
684
986
|
|