@e280/sly 0.2.0-16 → 0.2.0-18

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.
Files changed (226) hide show
  1. package/README.md +159 -33
  2. package/package.json +11 -4
  3. package/s/{ui/base-element.ts → base/element.ts} +5 -5
  4. package/s/base/index.ts +5 -0
  5. package/s/{ui/base → base}/use.ts +4 -5
  6. package/s/{ui/base → base}/utils/attr-watcher.ts +1 -1
  7. package/s/base/utils/use-attrs.ts +27 -0
  8. package/s/demo/views/counter.ts +3 -3
  9. package/s/demo/views/demo.ts +2 -2
  10. package/s/demo/views/fastcount.ts +2 -2
  11. package/s/demo/views/loaders.ts +7 -7
  12. package/s/dom/attrs/attrs.ts +3 -3
  13. package/s/dom/attrs/parts/attr-proxies.ts +3 -3
  14. package/s/dom/dom.ts +3 -3
  15. package/s/dom/index.ts +4 -0
  16. package/s/dom/parts/el.ts +2 -2
  17. package/s/index.ts +6 -19
  18. package/s/loaders/index.barrel.ts +9 -0
  19. package/s/loaders/index.ts +3 -0
  20. package/s/{ops/loaders/make-loader.ts → loaders/make.ts} +3 -7
  21. package/s/loaders/mock.ts +11 -0
  22. package/s/{ops/loaders → loaders}/parts/anims.ts +1 -1
  23. package/s/{ops/loaders → loaders}/parts/ascii-anim.ts +4 -3
  24. package/s/{ops/loaders → loaders}/parts/error-display.ts +2 -2
  25. package/s/loaders/types.ts +6 -0
  26. package/s/loot/index.barrel.ts +5 -0
  27. package/s/loot/index.ts +1 -3
  28. package/s/ops/index.ts +5 -0
  29. package/s/spa/index.barrel.ts +6 -0
  30. package/s/spa/index.ts +3 -0
  31. package/s/spa/plumbing/braces.ts +76 -0
  32. package/s/spa/plumbing/primitives.ts +85 -0
  33. package/s/spa/plumbing/router-core.ts +49 -0
  34. package/s/spa/plumbing/types.ts +39 -0
  35. package/s/spa/router.ts +49 -0
  36. package/s/spa/spa.test.ts +91 -0
  37. package/s/tests.test.ts +4 -1
  38. package/s/view/index.ts +6 -0
  39. package/s/{ui → view}/types.ts +3 -3
  40. package/s/{ui/view → view/utils}/make-component.ts +3 -3
  41. package/s/{ui/view → view/utils}/make-view.ts +1 -1
  42. package/s/{ui/view → view/utils}/parts/capsule.ts +3 -3
  43. package/s/{ui → view}/view.ts +3 -3
  44. package/x/base/css-reset.js.map +1 -0
  45. package/x/{ui/base-element.d.ts → base/element.d.ts} +2 -2
  46. package/x/{ui/base-element.js → base/element.js} +5 -5
  47. package/x/base/element.js.map +1 -0
  48. package/x/base/index.d.ts +3 -0
  49. package/x/base/index.js +4 -0
  50. package/x/base/index.js.map +1 -0
  51. package/x/{ui/base → base}/use.d.ts +3 -3
  52. package/x/{ui/base → base}/use.js +3 -3
  53. package/x/base/use.js.map +1 -0
  54. package/x/base/utils/apply-styles.js.map +1 -0
  55. package/x/{ui/base → base}/utils/attr-watcher.js +1 -1
  56. package/x/base/utils/attr-watcher.js.map +1 -0
  57. package/x/base/utils/mounts.js.map +1 -0
  58. package/x/base/utils/reactor.js.map +1 -0
  59. package/x/base/utils/use-attrs.d.ts +11 -0
  60. package/x/base/utils/use-attrs.js +19 -0
  61. package/x/base/utils/use-attrs.js.map +1 -0
  62. package/x/demo/demo.bundle.min.js +19 -19
  63. package/x/demo/demo.bundle.min.js.map +4 -4
  64. package/x/demo/views/counter.d.ts +4 -4
  65. package/x/demo/views/counter.js +3 -3
  66. package/x/demo/views/counter.js.map +1 -1
  67. package/x/demo/views/demo.d.ts +1 -1
  68. package/x/demo/views/demo.js +2 -2
  69. package/x/demo/views/demo.js.map +1 -1
  70. package/x/demo/views/fastcount.d.ts +2 -2
  71. package/x/demo/views/fastcount.js +1 -1
  72. package/x/demo/views/fastcount.js.map +1 -1
  73. package/x/demo/views/loaders.js +6 -6
  74. package/x/demo/views/loaders.js.map +1 -1
  75. package/x/dom/attrs/attrs.d.ts +3 -3
  76. package/x/dom/attrs/attrs.js +3 -3
  77. package/x/dom/attrs/attrs.js.map +1 -1
  78. package/x/dom/attrs/parts/attr-proxies.d.ts +3 -3
  79. package/x/dom/attrs/parts/attr-proxies.js +3 -3
  80. package/x/dom/attrs/parts/attr-proxies.js.map +1 -1
  81. package/x/dom/dom.d.ts +4 -4
  82. package/x/dom/dom.js +2 -2
  83. package/x/dom/dom.js.map +1 -1
  84. package/x/dom/index.d.ts +2 -0
  85. package/x/dom/index.js +3 -0
  86. package/x/dom/index.js.map +1 -0
  87. package/x/dom/parts/el.d.ts +1 -1
  88. package/x/dom/parts/el.js +1 -1
  89. package/x/dom/parts/el.js.map +1 -1
  90. package/x/index.d.ts +6 -16
  91. package/x/index.html +2 -2
  92. package/x/index.js +6 -16
  93. package/x/index.js.map +1 -1
  94. package/x/loaders/index.barrel.d.ts +6 -0
  95. package/x/loaders/index.barrel.js +7 -0
  96. package/x/loaders/index.barrel.js.map +1 -0
  97. package/x/loaders/index.d.ts +1 -0
  98. package/x/loaders/index.js +2 -0
  99. package/x/loaders/index.js.map +1 -0
  100. package/x/loaders/make.d.ts +3 -0
  101. package/x/loaders/make.js +6 -0
  102. package/x/loaders/make.js.map +1 -0
  103. package/x/loaders/mock.d.ts +2 -0
  104. package/x/loaders/mock.js +8 -0
  105. package/x/loaders/mock.js.map +1 -0
  106. package/x/{ops/loaders → loaders}/parts/anims.d.ts +1 -1
  107. package/x/loaders/parts/anims.js.map +1 -0
  108. package/x/{ops/loaders → loaders}/parts/ascii-anim.d.ts +2 -2
  109. package/x/{ops/loaders → loaders}/parts/ascii-anim.js +2 -2
  110. package/x/loaders/parts/ascii-anim.js.map +1 -0
  111. package/x/loaders/parts/error-display.d.ts +1 -0
  112. package/x/{ops/loaders → loaders}/parts/error-display.js +2 -2
  113. package/x/loaders/parts/error-display.js.map +1 -0
  114. package/x/loaders/types.d.ts +3 -0
  115. package/x/loaders/types.js.map +1 -0
  116. package/x/loot/index.barrel.d.ts +3 -0
  117. package/x/loot/index.barrel.js +4 -0
  118. package/x/loot/index.barrel.js.map +1 -0
  119. package/x/loot/index.d.ts +1 -3
  120. package/x/loot/index.js +1 -3
  121. package/x/loot/index.js.map +1 -1
  122. package/x/ops/index.d.ts +3 -0
  123. package/x/ops/index.js +4 -0
  124. package/x/ops/index.js.map +1 -0
  125. package/x/spa/index.barrel.d.ts +4 -0
  126. package/x/spa/index.barrel.js +3 -0
  127. package/x/spa/index.barrel.js.map +1 -0
  128. package/x/spa/index.d.ts +1 -0
  129. package/x/spa/index.js +2 -0
  130. package/x/spa/index.js.map +1 -0
  131. package/x/spa/plumbing/braces.d.ts +12 -0
  132. package/x/spa/plumbing/braces.js +55 -0
  133. package/x/spa/plumbing/braces.js.map +1 -0
  134. package/x/spa/plumbing/primitives.d.ts +22 -0
  135. package/x/spa/plumbing/primitives.js +65 -0
  136. package/x/spa/plumbing/primitives.js.map +1 -0
  137. package/x/spa/plumbing/router-core.d.ts +13 -0
  138. package/x/spa/plumbing/router-core.js +38 -0
  139. package/x/spa/plumbing/router-core.js.map +1 -0
  140. package/x/spa/plumbing/types.d.ts +34 -0
  141. package/x/spa/plumbing/types.js +2 -0
  142. package/x/spa/plumbing/types.js.map +1 -0
  143. package/x/spa/router.d.ts +16 -0
  144. package/x/spa/router.js +39 -0
  145. package/x/spa/router.js.map +1 -0
  146. package/x/spa/spa.test.d.ts +15 -0
  147. package/x/spa/spa.test.js +78 -0
  148. package/x/spa/spa.test.js.map +1 -0
  149. package/x/tests.test.js +4 -1
  150. package/x/tests.test.js.map +1 -1
  151. package/x/view/index.d.ts +4 -0
  152. package/x/view/index.js +5 -0
  153. package/x/view/index.js.map +1 -0
  154. package/x/{ui → view}/types.d.ts +3 -3
  155. package/x/view/types.js +2 -0
  156. package/x/{ui → view}/types.js.map +1 -1
  157. package/x/{ui/view → view/utils}/make-component.d.ts +1 -1
  158. package/x/{ui/view → view/utils}/make-component.js +1 -1
  159. package/x/view/utils/make-component.js.map +1 -0
  160. package/x/{ui/view → view/utils}/make-view.js +1 -1
  161. package/x/view/utils/make-view.js.map +1 -0
  162. package/x/{ui/view → view/utils}/parts/capsule.js +3 -3
  163. package/x/view/utils/parts/capsule.js.map +1 -0
  164. package/x/view/utils/parts/chain.js.map +1 -0
  165. package/x/view/utils/parts/context.js.map +1 -0
  166. package/x/view/utils/parts/directive.js.map +1 -0
  167. package/x/view/utils/parts/set-attrs.js.map +1 -0
  168. package/x/view/utils/parts/sly-view.js.map +1 -0
  169. package/x/{ui → view}/view.d.ts +2 -2
  170. package/x/{ui → view}/view.js +2 -2
  171. package/x/view/view.js.map +1 -0
  172. package/x/ops/loaders/make-loader.d.ts +0 -5
  173. package/x/ops/loaders/make-loader.js +0 -7
  174. package/x/ops/loaders/make-loader.js.map +0 -1
  175. package/x/ops/loaders/parts/anims.js.map +0 -1
  176. package/x/ops/loaders/parts/ascii-anim.js.map +0 -1
  177. package/x/ops/loaders/parts/error-display.d.ts +0 -1
  178. package/x/ops/loaders/parts/error-display.js.map +0 -1
  179. package/x/ui/base/css-reset.js.map +0 -1
  180. package/x/ui/base/use.js.map +0 -1
  181. package/x/ui/base/utils/apply-styles.js.map +0 -1
  182. package/x/ui/base/utils/attr-watcher.js.map +0 -1
  183. package/x/ui/base/utils/mounts.js.map +0 -1
  184. package/x/ui/base/utils/reactor.js.map +0 -1
  185. package/x/ui/base-element.js.map +0 -1
  186. package/x/ui/view/make-component.js.map +0 -1
  187. package/x/ui/view/make-view.js.map +0 -1
  188. package/x/ui/view/parts/capsule.js.map +0 -1
  189. package/x/ui/view/parts/chain.js.map +0 -1
  190. package/x/ui/view/parts/context.js.map +0 -1
  191. package/x/ui/view/parts/directive.js.map +0 -1
  192. package/x/ui/view/parts/set-attrs.js.map +0 -1
  193. package/x/ui/view/parts/sly-view.js.map +0 -1
  194. package/x/ui/view.js.map +0 -1
  195. /package/s/{ui/base → base}/css-reset.ts +0 -0
  196. /package/s/{ui/base → base}/utils/apply-styles.ts +0 -0
  197. /package/s/{ui/base → base}/utils/mounts.ts +0 -0
  198. /package/s/{ui/base → base}/utils/reactor.ts +0 -0
  199. /package/s/{ui/view → view/utils}/parts/chain.ts +0 -0
  200. /package/s/{ui/view → view/utils}/parts/context.ts +0 -0
  201. /package/s/{ui/view → view/utils}/parts/directive.ts +0 -0
  202. /package/s/{ui/view → view/utils}/parts/set-attrs.ts +0 -0
  203. /package/s/{ui/view → view/utils}/parts/sly-view.ts +0 -0
  204. /package/x/{ui/base → base}/css-reset.d.ts +0 -0
  205. /package/x/{ui/base → base}/css-reset.js +0 -0
  206. /package/x/{ui/base → base}/utils/apply-styles.d.ts +0 -0
  207. /package/x/{ui/base → base}/utils/apply-styles.js +0 -0
  208. /package/x/{ui/base → base}/utils/attr-watcher.d.ts +0 -0
  209. /package/x/{ui/base → base}/utils/mounts.d.ts +0 -0
  210. /package/x/{ui/base → base}/utils/mounts.js +0 -0
  211. /package/x/{ui/base → base}/utils/reactor.d.ts +0 -0
  212. /package/x/{ui/base → base}/utils/reactor.js +0 -0
  213. /package/x/{ops/loaders → loaders}/parts/anims.js +0 -0
  214. /package/x/{ui → loaders}/types.js +0 -0
  215. /package/x/{ui/view → view/utils}/make-view.d.ts +0 -0
  216. /package/x/{ui/view → view/utils}/parts/capsule.d.ts +0 -0
  217. /package/x/{ui/view → view/utils}/parts/chain.d.ts +0 -0
  218. /package/x/{ui/view → view/utils}/parts/chain.js +0 -0
  219. /package/x/{ui/view → view/utils}/parts/context.d.ts +0 -0
  220. /package/x/{ui/view → view/utils}/parts/context.js +0 -0
  221. /package/x/{ui/view → view/utils}/parts/directive.d.ts +0 -0
  222. /package/x/{ui/view → view/utils}/parts/directive.js +0 -0
  223. /package/x/{ui/view → view/utils}/parts/set-attrs.d.ts +0 -0
  224. /package/x/{ui/view → view/utils}/parts/set-attrs.js +0 -0
  225. /package/x/{ui/view → view/utils}/parts/sly-view.d.ts +0 -0
  226. /package/x/{ui/view → view/utils}/parts/sly-view.js +0 -0
package/README.md CHANGED
@@ -9,7 +9,9 @@
9
9
  - 🍋 [**#views**](#views) — shadow-dom'd, hooks-based, componentizable
10
10
  - 🪵 [**#base-element**](#base-element) — for a more classical experience
11
11
  - 🪄 [**#dom**](#dom) — the "it's not jquery" multitool
12
- - 🫛 [**#ops**](#ops) — tools for async operations and loading spinners
12
+ - 🫛 [**#ops**](#ops) — reactive tooling for async operations
13
+ - ⏳ [**#loaders**](#loaders) — animated loading spinners for rendering ops
14
+ - 💅 [**#spa**](#spa) — hash routing for your spa-day
13
15
  - 🪙 [**#loot**](#loot) — drag-and-drop facilities
14
16
  - 🧪 testing page — https://sly.e280.org/
15
17
 
@@ -18,6 +20,7 @@
18
20
  <br/><br/>
19
21
 
20
22
  ## 🦝 sly and friends
23
+ > `@e280/sly`
21
24
 
22
25
  ```sh
23
26
  npm install @e280/sly lit @e280/strata @e280/stz
@@ -29,24 +32,28 @@ npm install @e280/sly lit @e280/strata @e280/stz
29
32
  > - 🏂 [@e280/stz](https://github.com/e280/stz), our ts standard library
30
33
  > - 🐢 [@e280/scute](https://github.com/e280/scute), our buildy-bundly-buddy
31
34
 
35
+ > [!TIP]
36
+ > you can import everything in sly from `@e280/sly`, or from specific subpackages like `@e280/sly/view`, `@e280/sly/dom`, etc...
37
+
32
38
 
33
39
 
34
40
  <br/><br/>
35
41
  <a id="views"></a>
36
42
 
37
43
  ## 🍋🦝 sly views
38
- > *the crown jewel of sly*
44
+ > `@e280/sly/view`
45
+ > *the crown jewel of sly*
39
46
 
40
47
  ```ts
41
48
  view(use => () => html`<p>hello world</p>`)
42
49
  ```
43
50
 
44
51
  - 🪶 **no compile step** — just god's honest javascript, via [lit](https://lit.dev/)-html tagged-template-literals
45
- - 🥷 **shadow dom'd** — each 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)
46
- - 🪝 **hooks-based** — declarative rendering with the [`use.*`](#use) family of ergonomic hooks
52
+ - 🥷 **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)
53
+ - 🪝 **hooks-based** — declarative rendering with the [`use`](#use) family of ergonomic hooks
47
54
  - ⚡ **reactive** — they auto-rerender whenever any [strata](https://github.com/e280/strata)-compatible state changes
48
55
  - 🧐 **not components, per se** — they're comfy typescript-native ui building blocks [(technically, lit directives)](https://lit.dev/docs/templates/custom-directives/)
49
- - 🧩 **componentizable** — any view can be magically converted into a proper [web components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
56
+ - 🧩 **componentizable** — any view can be magically converted into a proper [web component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
50
57
 
51
58
  ### 🍋 view example
52
59
  ```ts
@@ -89,7 +96,7 @@ import {html, css} from "lit"
89
96
  ```
90
97
 
91
98
  ### 🍋 view settings
92
- - lame settings for views you should know about
99
+ - optional settings for views you should know about
93
100
  ```ts
94
101
  export const CoolView = view
95
102
  .settings({mode: "open", delegatesFocus: true})
@@ -98,7 +105,7 @@ import {html, css} from "lit"
98
105
  - all [attachShadow params](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#parameters) (like `mode` and `delegatesFocus`) are valid `settings`
99
106
  - note the `<slot></slot>` we'll use in the next example lol
100
107
 
101
- ### 🍋 view chain
108
+ ### 🍋 view chains
102
109
  - views have this sick chaining syntax for supplying more stuff at the template injection site
103
110
  ```ts
104
111
  dom.in(".app").render(html`
@@ -278,19 +285,30 @@ import {html, css} from "lit"
278
285
  v // 123
279
286
  ```
280
287
  - **use.attrs** — ergonomic typed html attribute access
281
- *(see [dom.attrs](#dom.attrs) for more details)*
282
- ```ts
283
- const attrs = use.attrs.spec({
284
- name: String,
285
- count: Number,
286
- active: Boolean,
287
- })
288
- ```
289
- ```ts
290
- attrs.name // "chase"
291
- attrs.count // 123
292
- attrs.active // true
293
- ```
288
+ - `use.attrs` is a bit different than `dom.attrs`, just to properly memoize .spec and .on for the render fn
289
+ - use.attrs.spec
290
+ ```ts
291
+ const attrs = use.attrs.spec({
292
+ name: String,
293
+ count: Number,
294
+ active: Boolean,
295
+ })
296
+ ```
297
+ ```ts
298
+ attrs.name // "chase"
299
+ attrs.count // 123
300
+ attrs.active // true
301
+ ```
302
+ - use.attrs.(strings/numbers/booleans)
303
+ ```ts
304
+ use.attrs.strings.name // "chase"
305
+ use.attrs.numbers.count // 123
306
+ use.attrs.booleans.active // true
307
+ ```
308
+ - use.attrs.on
309
+ ```ts
310
+ use.attrs.on(() => console.log("an attribute changed"))
311
+ ```
294
312
  - **use.render** — rerender the view (debounced)
295
313
  ```ts
296
314
  use.render()
@@ -344,14 +362,15 @@ import {html, css} from "lit"
344
362
  <a id="base-element"></a>
345
363
 
346
364
  ## 🪵🦝 sly base element
347
- > *the classic experience*
365
+ > `@e280/sly/base`
366
+ > *the classic experience*
348
367
 
349
368
  ```ts
350
369
  import {BaseElement, Use, dom} from "@e280/sly"
351
370
  import {html, css} from "lit"
352
371
  ```
353
372
 
354
- `BaseElement` is more of an old-timey class-based "boomer" approach to making web components, but with a zoomer twist — its `render` method gives you the same `use` hooks that views enjoy.
373
+ `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.
355
374
 
356
375
  👮 a *BaseElement* is not a *View*, and cannot be converted into a *View*.
357
376
 
@@ -440,7 +459,8 @@ import {html, css} from "lit"
440
459
  <a id="dom"></a>
441
460
 
442
461
  ## 🪄🦝 sly dom
443
- > *the "it's not jquery!" multitool*
462
+ > `@e280/sly/dom`
463
+ > *the "it's not jquery!" multitool*
444
464
 
445
465
  ```ts
446
466
  import {dom} from "@e280/sly"
@@ -518,9 +538,9 @@ import {dom} from "@e280/sly"
518
538
  ```
519
539
  or if you wanna be more loosey-goosy, skip the spec
520
540
  ```ts
521
- dom.attrs(element).string.name = "pimsley"
522
- dom.attrs(element).number.count = 125
523
- dom.attrs(element).boolean.active = true
541
+ dom.attrs(element).strings.name = "pimsley"
542
+ dom.attrs(element).numbers.count = 125
543
+ dom.attrs(element).booleans.active = true
524
544
  ```
525
545
 
526
546
 
@@ -529,11 +549,12 @@ import {dom} from "@e280/sly"
529
549
  <a id="ops"></a>
530
550
 
531
551
  ## 🫛🦝 sly ops
532
- > *tools for async operations and loading spinners*
552
+ > `@e280/sly/ops`
553
+ > *tools for async operations and loading spinners*
533
554
 
534
555
  ```ts
535
556
  import {nap} from "@e280/stz"
536
- import {Pod, podium, Op, makeLoader, anims} from "@e280/sly"
557
+ import {Pod, podium, Op, loaders} from "@e280/sly"
537
558
  ```
538
559
 
539
560
  ### 🫛 pods: loading/ready/error
@@ -632,14 +653,29 @@ import {Pod, podium, Op, makeLoader, anims} from "@e280/sly"
632
653
  - loading if any ops are in loading, otherwise
633
654
  - ready if all the ops are ready
634
655
 
635
- ### 🫛 loaders: animated loading spinners
636
- - create a `loader` using `makeLoader`
656
+
657
+
658
+ <br/><br/>
659
+ <a id="loaders"></a>
660
+
661
+ ## ⏳🦝 sly loaders
662
+ > `@e280/sly/loaders`
663
+ > *animated loading spinners for ops*
664
+
665
+ ```ts
666
+ import {loaders} from "@e280/sly"
667
+ ```
668
+
669
+ ### ⏳ make a loader, choose an anim
670
+ - create a loader fn
637
671
  ```ts
638
- const loader = makeLoader(anims.dots)
672
+ const loader = loaders.make(loaders.anims.dots)
639
673
  ```
640
674
  - see all the anims available on the testing page https://sly.e280.org/
641
675
  - ngl, i made too many.. *i was having fun, okay?*
642
- - use the loader to render your op
676
+
677
+ ### ⏳ render an op with it
678
+ - use your loader to render an op
643
679
  ```ts
644
680
  return html`
645
681
  <h2>cool stuff</h2>
@@ -655,11 +691,101 @@ import {Pod, podium, Op, makeLoader, anims} from "@e280/sly"
655
691
 
656
692
 
657
693
 
694
+ <br/><br/>
695
+ <a id="spa"></a>
696
+
697
+ ## 💅🦝 sly spa
698
+ > `@e280/sly/spa`
699
+ > *hash router for single-page-apps*
700
+
701
+ ```ts
702
+ import {spa, html} from "@e280/sly"
703
+ ```
704
+
705
+ ### 💅 spa.Router basics
706
+ - **make a spa router**
707
+ ```ts
708
+ const router = new spa.Router({
709
+ routes: {
710
+ home: spa.route("#/", async() => html`home`),
711
+ settings: spa.route("#/settings", async() => html`settings`),
712
+ user: spa.route("#/user/{userId}", async({userId}) => html`user ${userId}`),
713
+ },
714
+ })
715
+ ```
716
+ - all route strings must start with `#/`
717
+ - use braces like `{userId}` to accept string params
718
+ - home-equivalent hashes like `""` and `"#"` are normalized to `"#/"`
719
+ - 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*
720
+ - you can provide `loader` option if you want to specify the loading spinner (defaults to `loaders.make()`)
721
+ - you can provide `notFound` option, if you want to specify what is shown on invalid routes (defaults to `() => null`)
722
+ - when `auto` is true (default), the router calls `.refresh()` and `.listen()` in the constructor.. set it to `false` if you want manual control
723
+ - you can set `auto` option false if you want to omit the default initial refresh and listen calls
724
+ - **render your current page**
725
+ ```ts
726
+ return html`
727
+ <div class="my-page">
728
+ ${router.render()}
729
+ </div>
730
+ `
731
+ ```
732
+ - returns lit content
733
+ - shows a loading spinner when pages are loading
734
+ - will display the notFound content for invalid routes (defaults to null)
735
+ - **perform navigations**
736
+ - go to settings page
737
+ ```ts
738
+ await router.nav.settings.go()
739
+ // goes to "#/settings"
740
+ ```
741
+ - go to user page
742
+ ```ts
743
+ await router.nav.user.go("123")
744
+ // goes to "#/user/123"
745
+ ```
746
+
747
+ ### 💅 spa.Router advanced
748
+ - **generate a route's hash string**
749
+ ```ts
750
+ const hash = router.nav.user.hash("123")
751
+ // "#/user/123"
752
+
753
+ html`<a href="${hash}">user 123</a>`
754
+ ```
755
+ - **check if a route is the currently-active one**
756
+ ```ts
757
+ const hash = router.nav.user.active
758
+ // true
759
+ ```
760
+ - **force-refresh the router**
761
+ ```ts
762
+ await router.refresh()
763
+ ```
764
+ - **force-navigate the router by hash**
765
+ ```ts
766
+ await router.refresh("#/user/123")
767
+ ```
768
+ - **get the current hash string (normalized)**
769
+ ```ts
770
+ router.hash
771
+ // "#/user/123"
772
+ ```
773
+ - **the `route(...)` helper fn enables the braces-params syntax**
774
+ - but, if you wanna do it differently, you *can* implement your own hash parser to do your own funky syntax
775
+ - **dispose the router when you're done with it**
776
+ ```ts
777
+ router.dispose()
778
+ // stop listening to hashchange events
779
+ ```
780
+
781
+
782
+
658
783
  <br/><br/>
659
784
  <a id="loot"></a>
660
785
 
661
786
  ## 🪙🦝 loot
662
- > *drag-and-drop facilities*
787
+ > `@e280/sly/loot`
788
+ > *drag-and-drop facilities*
663
789
 
664
790
  ```ts
665
791
  import {loot, view, dom} from "@e280/sly"
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "@e280/sly",
3
- "version": "0.2.0-16",
3
+ "version": "0.2.0-18",
4
4
  "description": "web shadow views",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./x/index.js",
8
8
  "exports": {
9
- ".": "./x/index.js"
9
+ ".": "./x/index.js",
10
+ "./base": "./x/base/index.js",
11
+ "./dom": "./x/dom/index.js",
12
+ "./loaders": "./x/loaders/index.js",
13
+ "./loot": "./x/loot/index.js",
14
+ "./ops": "./x/ops/index.js",
15
+ "./spa": "./x/spa/index.js",
16
+ "./view": "./x/view/index.js"
10
17
  },
11
18
  "files": [
12
19
  "x",
@@ -16,8 +23,8 @@
16
23
  "lit": "^3.3.1"
17
24
  },
18
25
  "dependencies": {
19
- "@e280/strata": "^0.2.0-13",
20
- "@e280/stz": "^0.2.5"
26
+ "@e280/strata": "^0.2.0-14",
27
+ "@e280/stz": "^0.2.6"
21
28
  },
22
29
  "devDependencies": {
23
30
  "@e280/science": "^0.1.2",
@@ -3,11 +3,11 @@ import {debounce} from "@e280/stz"
3
3
  import {CSSResultGroup} from "lit"
4
4
 
5
5
  import {dom} from "../dom/dom.js"
6
- import {Content} from "./types.js"
7
- import {Reactor} from "./base/utils/reactor.js"
8
- import {AttrWatcher} from "./base/utils/attr-watcher.js"
9
- import {applyStyles} from "./base/utils/apply-styles.js"
10
- import {Use, _disconnect, _reconnect, _wrap} from "./base/use.js"
6
+ import {Content} from "../view/types.js"
7
+ import {Reactor} from "./utils/reactor.js"
8
+ import {AttrWatcher} from "./utils/attr-watcher.js"
9
+ import {applyStyles} from "./utils/apply-styles.js"
10
+ import {Use, _disconnect, _reconnect, _wrap} from "./use.js"
11
11
 
12
12
  export class BaseElement extends HTMLElement {
13
13
  static styles: CSSResultGroup | undefined
@@ -0,0 +1,5 @@
1
+
2
+ export * from "../base/css-reset.js"
3
+ export * from "../base/element.js"
4
+ export * from "../base/use.js"
5
+
@@ -3,10 +3,9 @@ import {CSSResultGroup} from "lit"
3
3
  import {defer, MapG} from "@e280/stz"
4
4
  import {signal, SignalOptions} from "@e280/strata/signals"
5
5
 
6
- import {Op} from "../../ops/op.js"
7
- import {dom} from "../../dom/dom.js"
8
- import {Attrs} from "../../dom/types.js"
6
+ import {Op} from "../ops/op.js"
9
7
  import {Mounts} from "./utils/mounts.js"
8
+ import {UseAttrs} from "./utils/use-attrs.js"
10
9
  import {applyStyles} from "./utils/apply-styles.js"
11
10
 
12
11
  export const _wrap = Symbol()
@@ -14,7 +13,7 @@ export const _disconnect = Symbol()
14
13
  export const _reconnect = Symbol()
15
14
 
16
15
  export class Use {
17
- attrs: Attrs
16
+ readonly attrs: UseAttrs
18
17
 
19
18
  #runs = 0
20
19
  #position = 0
@@ -45,7 +44,7 @@ export class Use {
45
44
  public renderNow: () => void,
46
45
  public render: () => Promise<void>,
47
46
  ) {
48
- this.attrs = dom.attrs(this.element)
47
+ this.attrs = new UseAttrs(this)
49
48
  }
50
49
 
51
50
  get renderCount() {
@@ -1,5 +1,5 @@
1
1
 
2
- import {dom} from "../../../dom/dom.js"
2
+ import {dom} from "../../dom/dom.js"
3
3
 
4
4
  export class AttrWatcher {
5
5
  #stopper: (() => void) | undefined
@@ -0,0 +1,27 @@
1
+
2
+ import {Use} from "../use.js"
3
+ import {dom} from "../../dom/dom.js"
4
+ import {Attrs, AttrSpec} from "../../dom/types.js"
5
+
6
+ export class UseAttrs {
7
+ #use: Use
8
+ #attrs: Attrs
9
+
10
+ constructor(use: Use) {
11
+ this.#use = use
12
+ this.#attrs = dom.attrs(use.element)
13
+ }
14
+
15
+ get strings() { return this.#attrs.strings }
16
+ get numbers() { return this.#attrs.numbers }
17
+ get booleans() { return this.#attrs.booleans }
18
+
19
+ spec<A extends AttrSpec>(spec: A) {
20
+ return this.#use.once(() => this.#attrs.spec(spec))
21
+ }
22
+
23
+ on(fn: () => void) {
24
+ return this.#use.mount(() => this.#attrs.on(fn))
25
+ }
26
+ }
27
+
@@ -2,9 +2,9 @@
2
2
  import {css, html} from "lit"
3
3
 
4
4
  import {dom} from "../../dom/dom.js"
5
- import {view} from "../../ui/view.js"
6
- import {cssReset} from "../../ui/base/css-reset.js"
7
- import {BaseElement} from "../../ui/base-element.js"
5
+ import {view} from "../../view/view.js"
6
+ import {cssReset} from "../../base/css-reset.js"
7
+ import {BaseElement} from "../../base/element.js"
8
8
 
9
9
  export const CounterView = view(use => (start: number, step: number) => {
10
10
  use.name("counter")
@@ -1,10 +1,10 @@
1
1
 
2
2
  import {css, html} from "lit"
3
3
 
4
- import {view} from "../../ui/view.js"
4
+ import {view} from "../../view/view.js"
5
5
  import {CounterView} from "./counter.js"
6
6
  import {LoadersView} from "./loaders.js"
7
- import {cssReset} from "../../ui/base/css-reset.js"
7
+ import {cssReset} from "../../base/css-reset.js"
8
8
 
9
9
  export class DemoComponent extends (view.component(use => {
10
10
  use.name("demo")
@@ -3,8 +3,8 @@ import {css, html} from "lit"
3
3
  import {nap, repeat} from "@e280/stz"
4
4
 
5
5
  import {dom} from "../../dom/dom.js"
6
- import {Use} from "../../ui/base/use.js"
7
- import {BaseElement} from "../../ui/base-element.js"
6
+ import {Use} from "../../base/use.js"
7
+ import {BaseElement} from "../../base/element.js"
8
8
 
9
9
  export class FastcountElement extends BaseElement {
10
10
  static styles = css`span{color:orange}`
@@ -1,9 +1,9 @@
1
1
 
2
2
  import {css, html} from "lit"
3
3
  import {Op} from "../../ops/op.js"
4
- import {view} from "../../ui/view.js"
5
- import {cssReset} from "../../ui/base/css-reset.js"
6
- import {anims, makeLoader} from "../../ops/loaders/make-loader.js"
4
+ import {view} from "../../view/view.js"
5
+ import {loaders} from "../../loaders/index.js"
6
+ import {cssReset} from "../../base/css-reset.js"
7
7
 
8
8
  export const LoadersView = view(use => () => {
9
9
  use.name("loaders")
@@ -11,14 +11,14 @@ export const LoadersView = view(use => () => {
11
11
 
12
12
  const op = use.once(() => Op.loading())
13
13
 
14
- const loaders = use.once(() =>
15
- Object.entries(anims).map(([key, anim]) => ({
14
+ const library = use.once(() =>
15
+ Object.entries(loaders.anims).map(([key, anim]) => ({
16
16
  key,
17
- loader: makeLoader(anim)
17
+ loader: loaders.make(anim)
18
18
  }))
19
19
  )
20
20
 
21
- return loaders.map(({key, loader}) => html`
21
+ return library.map(({key, loader}) => html`
22
22
  <div data-anim="${key}">
23
23
  <span>${key}</span>
24
24
  <span>${loader(op, () => null)}</span>
@@ -8,9 +8,9 @@ import {AttrProxies} from "./parts/attr-proxies.js"
8
8
  export function attrs(element: HTMLElement) {
9
9
  const proxies = new AttrProxies(element)
10
10
  return {
11
- string: proxies.string,
12
- number: proxies.number,
13
- boolean: proxies.boolean,
11
+ strings: proxies.strings,
12
+ numbers: proxies.numbers,
13
+ booleans: proxies.booleans,
14
14
  on: (fn: () => void) => onAttrs(element, fn),
15
15
  spec: <A extends AttrSpec>(spec: A) => attrSpec(element, spec),
16
16
  }
@@ -5,7 +5,7 @@ import {attrFns} from "./attr-fns.js"
5
5
  export class AttrProxies {
6
6
  constructor(public element: HTMLElement) {}
7
7
 
8
- string = new Proxy({}, {
8
+ strings = new Proxy({}, {
9
9
  get: (_t, key: string) => (
10
10
  attrFns.get.string(this.element, key)
11
11
  ),
@@ -14,7 +14,7 @@ export class AttrProxies {
14
14
  ),
15
15
  }) as Record<string, string | undefined>
16
16
 
17
- number = new Proxy({}, {
17
+ numbers = new Proxy({}, {
18
18
  get: (_t, key: string) => (
19
19
  attrFns.get.number(this.element, key)
20
20
  ),
@@ -23,7 +23,7 @@ export class AttrProxies {
23
23
  ),
24
24
  }) as Record<string, number | undefined>
25
25
 
26
- boolean = new Proxy({}, {
26
+ booleans = new Proxy({}, {
27
27
  get: (_t, key: string) => (
28
28
  attrFns.get.boolean(this.element, key)
29
29
  ),
package/s/dom/dom.ts CHANGED
@@ -1,11 +1,11 @@
1
1
 
2
2
  import {render} from "lit"
3
+ import {el} from "./parts/el.js"
3
4
  import {AttrSpec} from "./types.js"
4
5
  import {attrs} from "./attrs/attrs.js"
5
- import {Content} from "../ui/types.js"
6
+ import {Content} from "../view/types.js"
7
+ import {eve, EveSpec} from "./parts/eve.js"
6
8
  import {register} from "./parts/register.js"
7
- import { eve, EveSpec } from "./parts/eve.js"
8
- import { el } from "./parts/el.js"
9
9
 
10
10
  export type Renderable = HTMLElement | ShadowRoot | DocumentFragment
11
11
  export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment
package/s/dom/index.ts ADDED
@@ -0,0 +1,4 @@
1
+
2
+ export * from "./types.js"
3
+ export * from "./dom.js"
4
+
package/s/dom/parts/el.ts CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
- import {AttrValue} from "../../ui/types.js"
3
- import {setAttrs} from "../../ui/view/parts/set-attrs.js"
2
+ import {AttrValue} from "../../view/types.js"
3
+ import {setAttrs} from "../../view/utils/parts/set-attrs.js"
4
4
 
5
5
  export function el<E extends HTMLElement>(
6
6
  tagName: string,
package/s/index.ts CHANGED
@@ -1,21 +1,8 @@
1
1
 
2
- export * from "./dom/types.js"
3
- export * from "./dom/dom.js"
4
-
5
- export * from "./ops/loaders/make-loader.js"
6
- export * from "./ops/loaders/parts/ascii-anim.js"
7
- export * from "./ops/loaders/parts/error-display.js"
8
- export * from "./ops/op.js"
9
- export * from "./ops/podium.js"
10
- export * from "./ops/types.js"
11
-
12
- export * as loot from "./loot/index.js"
13
-
14
- export * from "./ui/base/css-reset.js"
15
- export * from "./ui/base/use.js"
16
- export * from "./ui/view/parts/chain.js"
17
- export * from "./ui/view/parts/sly-view.js"
18
- export * from "./ui/base-element.js"
19
- export * from "./ui/types.js"
20
- export * from "./ui/view.js"
2
+ export * from "./dom/index.js"
3
+ export * from "./loaders/index.js"
4
+ export * from "./loot/index.js"
5
+ export * from "./ops/index.js"
6
+ export * from "./spa/index.js"
7
+ export * from "./view/index.js"
21
8
 
@@ -0,0 +1,9 @@
1
+
2
+ export * as anims from "./parts/anims.js"
3
+ export * from "./parts/ascii-anim.js"
4
+ export * from "./parts/error-display.js"
5
+ export * from "./make.js"
6
+ export * from "./mock.js"
7
+ export * from "./types.js"
8
+
9
+
@@ -0,0 +1,3 @@
1
+
2
+ export * as loaders from "./index.barrel.js"
3
+
@@ -1,14 +1,10 @@
1
1
 
2
- import {Op} from "../op.js"
2
+ import {Loader} from "./types.js"
3
3
  import {earth} from "./parts/anims.js"
4
- import {Content} from "../../ui/types.js"
4
+ import type {Content} from "../view/types.js"
5
5
  import {ErrorDisplay} from "./parts/error-display.js"
6
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(
7
+ export function make(
12
8
  loading: () => Content = earth,
13
9
  error: (error: any) => Content = (error: any) => ErrorDisplay(error),
14
10
  ): Loader {
@@ -0,0 +1,11 @@
1
+
2
+ import {Loader} from "./types.js"
3
+
4
+ export function mock(): Loader {
5
+ return (op, ready) => op.select({
6
+ ready,
7
+ loading: () => `[loading]`,
8
+ error: () => `[error]`,
9
+ })
10
+ }
11
+
@@ -1,6 +1,6 @@
1
1
 
2
2
  import {makeAsciiAnim} from "./ascii-anim.js"
3
- import {Content} from "../../../ui/types.js"
3
+ import type {Content} from "../../view/types.js"
4
4
 
5
5
  const fast = 20
6
6
  const mid = 10