@e280/sly 0.3.0-7 → 0.3.0-9

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 (109) hide show
  1. package/README.md +36 -10
  2. package/package.json +19 -25
  3. package/s/demo/demo.bundle.ts +4 -0
  4. package/s/demo/views/demo.ts +3 -0
  5. package/s/demo/views/loaders.ts +2 -2
  6. package/s/demo/views/time-light.ts +19 -0
  7. package/s/demo/views/time-shadow.ts +22 -0
  8. package/s/index.ts +2 -2
  9. package/s/{loaders → loader}/index.barrel.ts +0 -1
  10. package/s/{loaders → loader}/index.ts +0 -1
  11. package/s/{loaders → loader}/types.ts +1 -1
  12. package/s/view/elements/light.ts +14 -0
  13. package/s/view/elements/shadow.ts +52 -0
  14. package/s/view/hooks/use-attrs.ts +14 -0
  15. package/s/view/hooks/use-op.ts +1 -1
  16. package/s/view/index.ts +4 -0
  17. package/x/demo/demo.bundle.js +3 -0
  18. package/x/demo/demo.bundle.js.map +1 -1
  19. package/x/demo/demo.bundle.min.js +22 -15
  20. package/x/demo/demo.bundle.min.js.map +4 -4
  21. package/x/demo/views/demo.js +3 -0
  22. package/x/demo/views/demo.js.map +1 -1
  23. package/x/demo/views/loaders.js +2 -2
  24. package/x/demo/views/loaders.js.map +1 -1
  25. package/x/demo/views/time-light.d.ts +359 -0
  26. package/x/demo/views/time-light.js +16 -0
  27. package/x/demo/views/time-light.js.map +1 -0
  28. package/x/demo/views/time-shadow.d.ts +365 -0
  29. package/x/demo/views/time-shadow.js +18 -0
  30. package/x/demo/views/time-shadow.js.map +1 -0
  31. package/x/index.d.ts +2 -2
  32. package/x/index.html +2 -2
  33. package/x/index.js +2 -2
  34. package/x/index.js.map +1 -1
  35. package/x/{loaders → loader}/index.barrel.d.ts +0 -1
  36. package/x/loader/index.barrel.js.map +1 -0
  37. package/x/{loaders → loader}/index.d.ts +0 -1
  38. package/x/loader/index.js.map +1 -0
  39. package/x/loader/make.js.map +1 -0
  40. package/x/loader/mock.js.map +1 -0
  41. package/x/loader/parts/anims.js.map +1 -0
  42. package/x/loader/parts/ascii-anim.js.map +1 -0
  43. package/x/loader/parts/error-display.js.map +1 -0
  44. package/x/{loaders → loader}/types.d.ts +1 -1
  45. package/x/{loaders → loader}/types.js.map +1 -1
  46. package/x/op/index.js.map +1 -0
  47. package/x/op/op.js.map +1 -0
  48. package/x/op/podium.js.map +1 -0
  49. package/x/{ops → op}/types.js.map +1 -1
  50. package/x/{tests.test.js → test.js} +1 -1
  51. package/x/test.js.map +1 -0
  52. package/x/view/elements/light.d.ts +357 -0
  53. package/x/view/elements/light.js +10 -0
  54. package/x/view/elements/light.js.map +1 -0
  55. package/x/view/elements/shadow.d.ts +366 -0
  56. package/x/view/elements/shadow.js +42 -0
  57. package/x/view/elements/shadow.js.map +1 -0
  58. package/x/view/hooks/use-attrs.d.ts +2 -0
  59. package/x/view/hooks/use-attrs.js +11 -0
  60. package/x/view/hooks/use-attrs.js.map +1 -0
  61. package/x/view/hooks/use-op.d.ts +1 -1
  62. package/x/view/hooks/use-op.js +1 -1
  63. package/x/view/hooks/use-op.js.map +1 -1
  64. package/x/view/index.d.ts +3 -0
  65. package/x/view/index.js +3 -0
  66. package/x/view/index.js.map +1 -1
  67. package/x/loaders/index.barrel.js.map +0 -1
  68. package/x/loaders/index.js.map +0 -1
  69. package/x/loaders/make.js.map +0 -1
  70. package/x/loaders/mock.js.map +0 -1
  71. package/x/loaders/parts/anims.js.map +0 -1
  72. package/x/loaders/parts/ascii-anim.js.map +0 -1
  73. package/x/loaders/parts/error-display.js.map +0 -1
  74. package/x/ops/index.js.map +0 -1
  75. package/x/ops/op.js.map +0 -1
  76. package/x/ops/podium.js.map +0 -1
  77. package/x/tests.test.js.map +0 -1
  78. /package/s/{loaders → loader}/make.ts +0 -0
  79. /package/s/{loaders → loader}/mock.ts +0 -0
  80. /package/s/{loaders → loader}/parts/anims.ts +0 -0
  81. /package/s/{loaders → loader}/parts/ascii-anim.ts +0 -0
  82. /package/s/{loaders → loader}/parts/error-display.ts +0 -0
  83. /package/s/{ops → op}/index.ts +0 -0
  84. /package/s/{ops → op}/op.ts +0 -0
  85. /package/s/{ops → op}/podium.ts +0 -0
  86. /package/s/{ops → op}/types.ts +0 -0
  87. /package/s/{tests.test.ts → test.ts} +0 -0
  88. /package/x/{loaders → loader}/index.barrel.js +0 -0
  89. /package/x/{loaders → loader}/index.js +0 -0
  90. /package/x/{loaders → loader}/make.d.ts +0 -0
  91. /package/x/{loaders → loader}/make.js +0 -0
  92. /package/x/{loaders → loader}/mock.d.ts +0 -0
  93. /package/x/{loaders → loader}/mock.js +0 -0
  94. /package/x/{loaders → loader}/parts/anims.d.ts +0 -0
  95. /package/x/{loaders → loader}/parts/anims.js +0 -0
  96. /package/x/{loaders → loader}/parts/ascii-anim.d.ts +0 -0
  97. /package/x/{loaders → loader}/parts/ascii-anim.js +0 -0
  98. /package/x/{loaders → loader}/parts/error-display.d.ts +0 -0
  99. /package/x/{loaders → loader}/parts/error-display.js +0 -0
  100. /package/x/{loaders → loader}/types.js +0 -0
  101. /package/x/{ops → op}/index.d.ts +0 -0
  102. /package/x/{ops → op}/index.js +0 -0
  103. /package/x/{ops → op}/op.d.ts +0 -0
  104. /package/x/{ops → op}/op.js +0 -0
  105. /package/x/{ops → op}/podium.d.ts +0 -0
  106. /package/x/{ops → op}/podium.js +0 -0
  107. /package/x/{ops → op}/types.d.ts +0 -0
  108. /package/x/{ops → op}/types.js +0 -0
  109. /package/x/{tests.test.d.ts → test.d.ts} +0 -0
package/README.md CHANGED
@@ -23,12 +23,13 @@ npm install lit @e280/sly @e280/strata @e280/stz
23
23
  <a id="views"></a>
24
24
 
25
25
  ## 🎭 views
26
- > *"flourish in the light.. or thrive in the darkness"*
26
+ > *reactive lit-html views*
27
27
 
28
+ - 🔮 [**see codepen demo,**](https://codepen.io/editor/ChaseMoskal/pen/019cd681-722b-7f51-a961-bc16e3d524a9) plain html (no build!)
28
29
  - 🌗 **light or shadow,** render nakedly on the page, or within a cozy shadow bubble
29
30
  - 🪝 **hooks-based,** familiar react-style [hooks](#hooks)
30
31
  - ⚡ **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
+ - 🪶 **no compile step,** just god's honest javascript via [lit](https://lit.dev/)-html tagged-templates
32
33
  - 🧩 **not web components,** no dom registration needed, just vibes and good typings
33
34
 
34
35
  ```ts
@@ -41,7 +42,7 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
41
42
  ```
42
43
 
43
44
  ### 🌞 light views
44
- > *"just pretend it's react, without jsx"*
45
+ > *just pretend it's like react!*
45
46
 
46
47
  - **define a light view**
47
48
  ```ts
@@ -64,12 +65,9 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
64
65
  ${MyCounter(123)}
65
66
  `)
66
67
  ```
67
- - light views have no host element, rendered output looks like:
68
- ```html
69
- <h1>my cool counter demo</h1>
70
- <button>123</button>
71
- ```
72
- - **light views are naked,** they don't have a containing host element
68
+ - **remember, light views are naked.**
69
+ so they don't have a containing host element,
70
+ and they can't have their own styles.
73
71
 
74
72
  ### 🌚 shadow views
75
73
  > *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)*
@@ -132,6 +130,24 @@ export const MyShadowView = shadow(() => html`<p>shrouded in darkness</p>`)
132
130
  const MyShadowView = customShadow(() => html`<p>shrouded in darkness</p>`)
133
131
  ```
134
132
 
133
+ ### 🍨 web components
134
+ > *web-native custom elements*
135
+
136
+ - **they use hooks like the views, but they don't take props**
137
+ ```ts
138
+ import {html} from "lit"
139
+ import {lightElement, shadowElement} from "@e280/sly"
140
+
141
+ const MyLight = lightElement(() => html`hello`)
142
+ const MyShadow = shadowElement(() => html`hello`)
143
+
144
+ dom.register({MyLight, MyShadow})
145
+ ```
146
+ ```html
147
+ <my-light></my-light>
148
+ <my-shadow></my-shadow>
149
+ ```
150
+
135
151
 
136
152
 
137
153
  <br/><br/>
@@ -164,6 +180,16 @@ you must not call these hooks under if-conditionals, or for-loops, or inside cal
164
180
  ```ts
165
181
  const shadow = useShadow()
166
182
  ```
183
+ - **useAttrs,** access host element attributes (and rerender on attr changes)
184
+ ```ts
185
+ const attrs = useAttrs({
186
+ name: String,
187
+ count: Number,
188
+ active: Boolean,
189
+ })
190
+
191
+ attrs.count = 123 // set the attr
192
+ ```
167
193
 
168
194
  ### 🌞 universal hooks
169
195
  - **useState,** react-like hook to create some reactive state (we prefer signals)
@@ -313,7 +339,7 @@ import {Pod, podium, Op, loaders} from "@e280/sly"
313
339
  podium.value(["ready", 123])
314
340
  // 123
315
341
  ```
316
- - see more at [podium.ts](./s/ops/podium.ts)
342
+ - see more at [podium.ts](./s/op/podium.ts)
317
343
 
318
344
  ### 🫛 ops: nice pod ergonomics
319
345
  - an `Op<V>` wraps a pod with a strata signal for reactivity
package/package.json CHANGED
@@ -1,50 +1,43 @@
1
1
  {
2
2
  "name": "@e280/sly",
3
- "version": "0.3.0-7",
3
+ "version": "0.3.0-9",
4
4
  "description": "web shadow views",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
+ "files": [
8
+ "x",
9
+ "s"
10
+ ],
7
11
  "main": "./x/index.js",
8
12
  "exports": {
9
13
  ".": "./x/index.js",
10
14
  "./dom": "./x/dom/index.js",
11
- "./loaders": "./x/loaders/index.js",
15
+ "./loader": "./x/loader/index.js",
12
16
  "./loot": "./x/loot/index.js",
13
- "./ops": "./x/ops/index.js",
17
+ "./op": "./x/op/index.js",
14
18
  "./view": "./x/view/index.js"
15
19
  },
16
- "files": [
17
- "x",
18
- "s"
19
- ],
20
+ "scripts": {
21
+ "build": "rm -rf x && mkdir x && ln -s '$(realpath s)' x/s && ln -s '$(realpath assets)' x/assets && tsc && scute -v",
22
+ "start": "octo 'tsc -w' 'scute -wv' 'node --watch x/test.js' 'http-server x'",
23
+ "count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +",
24
+ "test": "node x/test.js"
25
+ },
20
26
  "peerDependencies": {
21
27
  "lit": "^3.3.2"
22
28
  },
23
29
  "dependencies": {
24
- "@e280/strata": "^0.3.0-1",
30
+ "@e280/strata": "^0.3.0-2",
25
31
  "@e280/stz": "^0.2.24"
26
32
  },
27
33
  "devDependencies": {
34
+ "@e280/octo": "^0.1.0-12",
28
35
  "@e280/science": "^0.1.8",
29
- "@e280/scute": "^0.2.2",
36
+ "@e280/scute": "^0.3.0-1",
30
37
  "http-server": "^14.1.1",
31
38
  "npm-run-all": "^4.1.5",
32
39
  "typescript": "^5.9.3"
33
40
  },
34
- "scripts": {
35
- "build": "run-s _clean _ln _tsc _scute",
36
- "start": "octo 'scute -vw' 'tsc -w' 'node --watch x/tests.test.js' 'http-server x'",
37
- "count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +",
38
- "test": "node x/tests.test.js",
39
- "test-inspect": "node inspect x/tests.test.js",
40
- "_clean": "rm -rf x && mkdir x",
41
- "_tsc": "tsc",
42
- "_scute": "scute -v",
43
- "_ln": "run-s _ln:s _ln:assets",
44
- "_ln:s": "ln -s \"$(realpath s)\" x/s",
45
- "_ln:assets": "ln -s \"$(realpath assets)\" x/assets",
46
- "_lnx:stz": "rm -rf node_modules/@e280/stz && ln -s \"$(realpath ../stz)\" node_modules/@e280/stz"
47
- },
48
41
  "author": "Chase Moskal <chasemoskal@gmail.com>",
49
42
  "homepage": "https://github.com/e280/sly#readme",
50
43
  "repository": {
@@ -55,9 +48,10 @@
55
48
  "url": "https://github.com/e280/sly/issues"
56
49
  },
57
50
  "keywords": [
51
+ "lit",
52
+ "views",
58
53
  "shadow views",
59
54
  "shadow dom",
60
- "components",
61
- "lit"
55
+ "components"
62
56
  ]
63
57
  }
@@ -1,6 +1,10 @@
1
1
 
2
2
  import {dom} from "../dom/dom.js"
3
3
  import {Demo} from "./views/demo.js"
4
+ import {TimeLight} from "./views/time-light.js"
5
+ import {TimeShadow} from "./views/time-shadow.js"
6
+
7
+ dom.register({TimeShadow, TimeLight})
4
8
 
5
9
  dom.render(dom(".demo"), Demo())
6
10
  console.log("🦝 sly")
@@ -20,6 +20,9 @@ export const Demo = shadow(() => {
20
20
  })}
21
21
  </p>
22
22
 
23
+ <time-shadow></time-shadow>
24
+ <time-light></time-light>
25
+
23
26
  ${LoadersView()}
24
27
  `
25
28
  })
@@ -1,8 +1,8 @@
1
1
 
2
2
  import {css, html} from "lit"
3
- import {Op} from "../../ops/op.js"
3
+ import {Op} from "../../op/op.js"
4
4
  import {shadow} from "../../view/shadow.js"
5
- import {loaders} from "../../loaders/index.js"
5
+ import {loaders} from "../../loader/index.js"
6
6
  import {cssReset, useName, useOnce, useStyles} from "../../view/index.js"
7
7
 
8
8
  export const LoadersView = shadow(() => {
@@ -0,0 +1,19 @@
1
+
2
+ import {html} from "lit"
3
+ import {cycle, nap} from "@e280/stz"
4
+ import {useMount, useSignal} from "../../view/index.js"
5
+ import {lightElement} from "../../view/elements/light.js"
6
+
7
+ export class TimeLight extends lightElement(() => {
8
+ const $time = useSignal(Date.now())
9
+
10
+ useMount(() => cycle(async() => {
11
+ await nap(100)
12
+ $time(Date.now())
13
+ }))
14
+
15
+ return html`
16
+ <p>${$time()}</p>
17
+ `
18
+ }) {}
19
+
@@ -0,0 +1,22 @@
1
+
2
+ import {css, html} from "lit"
3
+ import {cycle, nap} from "@e280/stz"
4
+ import {shadowElement} from "../../view/elements/shadow.js"
5
+ import {useCss, useMount, useName, useSignal} from "../../view/index.js"
6
+
7
+ export class TimeShadow extends shadowElement(() => {
8
+ useName("time-shadow")
9
+ useCss(css`:host{display:inline-block} button{color:cyan}`)
10
+
11
+ const $time = useSignal(Date.now())
12
+
13
+ useMount(() => cycle(async() => {
14
+ await nap(100)
15
+ $time(Date.now())
16
+ }))
17
+
18
+ return html`
19
+ <p>${$time()}</p>
20
+ `
21
+ }) {}
22
+
package/s/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  export * from "./dom/index.js"
3
- export * from "./loaders/index.js"
3
+ export * from "./loader/index.js"
4
4
  export * from "./loot/index.js"
5
- export * from "./ops/index.js"
5
+ export * from "./op/index.js"
6
6
  export * from "./view/index.js"
7
7
 
@@ -1,6 +1,5 @@
1
1
 
2
2
  export * as anims from "./parts/anims.js"
3
- export type * from "./parts/anims.js"
4
3
  export * from "./parts/ascii-anim.js"
5
4
  export * from "./parts/error-display.js"
6
5
  export * from "./make.js"
@@ -1,4 +1,3 @@
1
1
 
2
2
  export * as loaders from "./index.barrel.js"
3
- export type * from "./index.barrel.js"
4
3
 
@@ -1,5 +1,5 @@
1
1
 
2
- import type {Op} from "../ops/op.js"
2
+ import type {Op} from "../op/op.js"
3
3
  import type {Content} from "../view/types.js"
4
4
 
5
5
  export type Loader = <V>(op: Op<V>, ready: (value: V) => Content) => Content
@@ -0,0 +1,14 @@
1
+
2
+ import {render} from "lit"
3
+ import {light} from "../light.js"
4
+ import {Content} from "../types.js"
5
+
6
+ export function lightElement(view: () => Content) {
7
+ const fn = light(view)
8
+
9
+ return class extends HTMLElement {
10
+ connectedCallback() { render(fn(), this) }
11
+ disconnectedCallback() { render(null, this) }
12
+ }
13
+ }
14
+
@@ -0,0 +1,52 @@
1
+
2
+ import {microbounce} from "@e280/stz"
3
+ import {render as litRender} from "lit"
4
+ import {Content} from "../types.js"
5
+ import {ShadowCx} from "../parts/cx.js"
6
+ import {hooks} from "../hooks/plumbing/hooks.js"
7
+ import {Reactivity} from "../parts/reactivity.js"
8
+ import {Hookscope} from "../hooks/plumbing/hookscope.js"
9
+
10
+ export function shadowElement(view: () => Content) {
11
+ return class extends HTMLElement {
12
+ #cx
13
+ #hookscope
14
+ #reactivity = new Reactivity()
15
+ #shadow = this.attachShadow({mode: "open"})
16
+
17
+ constructor() {
18
+ super()
19
+ const rerender = microbounce(() => {
20
+ if (!this.isConnected) return
21
+ const content = this.#renderContent()
22
+ litRender(content, this.#cx.shadow)
23
+ this.#cx.doneRender()
24
+ })
25
+ this.#cx = new ShadowCx(rerender, this, this.#shadow)
26
+ this.#hookscope = new Hookscope(this.#cx)
27
+ }
28
+
29
+ #renderContent() {
30
+ return this.#reactivity.observe(
31
+ () => hooks.wrap(this.#hookscope, () => view()),
32
+ this.#cx.render,
33
+ )
34
+ }
35
+
36
+ render() {
37
+ litRender(this.#renderContent(), this.#cx.shadow)
38
+ this.#cx.doneRender()
39
+ }
40
+
41
+ connectedCallback() {
42
+ this.#hookscope.mounts.remountAll()
43
+ this.#cx.render()
44
+ }
45
+
46
+ disconnectedCallback() {
47
+ this.#hookscope.mounts.unmountAll()
48
+ this.#reactivity.clear()
49
+ }
50
+ }
51
+ }
52
+
@@ -0,0 +1,14 @@
1
+
2
+ import {dom} from "../../dom/dom.js"
3
+ import {useOnce} from "./use-once.js"
4
+ import {useMount} from "./use-mount.js"
5
+ import {AttrSpec} from "../../dom/types.js"
6
+ import {useHost, useRender} from "./use-cx.js"
7
+
8
+ export function useAttrs<A extends AttrSpec>(spec: A) {
9
+ const host = useHost()
10
+ const rerender = useRender()
11
+ useMount(() => dom.attrs(host).on(rerender))
12
+ return useOnce(() => dom.attrs(host).spec(spec))
13
+ }
14
+
@@ -1,5 +1,5 @@
1
1
 
2
- import {Op} from "../../ops/op.js"
2
+ import {Op} from "../../op/op.js"
3
3
  import {useOnce} from "./use-once.js"
4
4
 
5
5
  export function useOp<Value>(fn: () => Promise<Value>) {
package/s/view/index.ts CHANGED
@@ -2,6 +2,10 @@
2
2
  export * from "./common/css-reset.js"
3
3
  export * from "./common/sly-shadow.js"
4
4
 
5
+ export * from "./elements/light.js"
6
+ export * from "./elements/shadow.js"
7
+
8
+ export * from "./hooks/use-attrs.js"
5
9
  export * from "./hooks/use-css.js"
6
10
  export * from "./hooks/use-cx.js"
7
11
  export * from "./hooks/use-life.js"
@@ -1,5 +1,8 @@
1
1
  import { dom } from "../dom/dom.js";
2
2
  import { Demo } from "./views/demo.js";
3
+ import { TimeLight } from "./views/time-light.js";
4
+ import { TimeShadow } from "./views/time-shadow.js";
5
+ dom.register({ TimeShadow, TimeLight });
3
6
  dom.render(dom(".demo"), Demo());
4
7
  console.log("🦝 sly");
5
8
  //# sourceMappingURL=demo.bundle.js.map
@@ -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,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;AAChC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA"}
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;AACpC,OAAO,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAC,UAAU,EAAC,MAAM,wBAAwB,CAAA;AAEjD,GAAG,CAAC,QAAQ,CAAC,EAAC,UAAU,EAAE,SAAS,EAAC,CAAC,CAAA;AAErC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;AAChC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA"}