@e280/sly 0.2.0-11 โ†’ 0.2.0-12

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 (3) hide show
  1. package/README.md +86 -63
  2. package/package.json +1 -1
  3. package/x/index.html +1 -1
package/README.md CHANGED
@@ -4,13 +4,13 @@
4
4
  # ๐Ÿฆ sly
5
5
  > *mischievous shadow views*
6
6
 
7
- [@e280](https://e280.org/)'s shiny new [lit](https://lit.dev/)-based frontend lib for webdevs. *(sly replaces its predecessor, [slate](https://github.com/benevolent-games/slate))*
7
+ [@e280](https://e280.org/)'s shiny new [lit](https://lit.dev/)-based frontend webdev library. *(sly replaces its predecessor, [slate](https://github.com/benevolent-games/slate))*
8
8
 
9
- - ๐Ÿ‹ [**views**](#views) โ€” hooks-based, shadow-dom'd, componentizable
10
- - ๐Ÿชต [**base element**](#base-element) โ€” for a more classical experience
11
- - ๐Ÿช„ [**dom**](#dom) โ€” the "it's not jquery" multitool
12
- - ๐Ÿซ› [**ops**](#ops) โ€” tools for async operations and loading spinners
13
- - ๐Ÿช™ [**loot**](#loot) โ€” drag-and-drop facilities
9
+ - ๐Ÿ‹ [**#views**](#views) โ€” shadow-dom'd, hooks-based, componentizable
10
+ - ๐Ÿชต [**#base-element**](#base-element) โ€” for a more classical experience
11
+ - ๐Ÿช„ [**#dom**](#dom) โ€” the "it's not jquery" multitool
12
+ - ๐Ÿซ› [**#ops**](#ops) โ€” tools for async operations and loading spinners
13
+ - ๐Ÿช™ [**#loot**](#loot) โ€” drag-and-drop facilities
14
14
  - ๐Ÿงช testing page โ€” https://sly.e280.org/
15
15
 
16
16
 
@@ -34,76 +34,77 @@ npm install @e280/sly lit @e280/strata @e280/stz
34
34
  <br/><br/>
35
35
  <a id="views"></a>
36
36
 
37
- ## ๐Ÿฆ๐Ÿ‹ sly views and components
38
- > *views are the crown jewel of sly.. shadow-dom'd.. hooks-based.. "ergonomics"..*
37
+ ## ๐Ÿฆ๐Ÿ‹ sly views
38
+ > *the crown jewel of sly*
39
39
 
40
40
  ```ts
41
41
  view(use => () => html`<p>hello world</p>`)
42
42
  ```
43
43
 
44
- - any view can be converted into a web component
45
- - views are not [web components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) per se, but they do have [shadow roots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) and support [slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)
46
- - views are typescript-native and comfy for webdevs building apps
47
- - views automatically rerender whenever any [strata-compatible](https://github.com/e280/strata) state changes
44
+ - ๐Ÿชถ **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
47
+ - โšก **reactive** โ€” they auto-rerender whenever any [strata](https://github.com/e280/strata)-compatible state changes
48
+ - ๐Ÿง **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)
48
50
 
49
51
  ### ๐Ÿ‹ view example
50
52
  ```ts
51
53
  import {view, dom, BaseElement} from "@e280/sly"
52
54
  import {html, css} from "lit"
53
55
  ```
54
- - **declare a view**
56
+ - **declare view**
55
57
  ```ts
56
58
  export const CounterView = view(use => (start: number) => {
57
- use.name("counter")
58
59
  use.styles(css`p {color: green}`)
59
60
 
60
61
  const $count = use.signal(start)
61
62
  const increment = () => $count.value++
62
63
 
63
64
  return html`
64
- <span>${$count.value}</span>
65
- <button @click="${increment}">+</button>
65
+ <button @click="${increment}">
66
+ ${$count.value}
67
+ </button>
66
68
  `
67
69
  })
68
70
  ```
69
- - each view renders into a `<sly-view view="counter">` host (where "counter" is the `use.name` you provided)
70
- - **inject a view into the dom**
71
+ - `$count` is a [strata signal](https://github.com/e280/strata#readme) *(we like those)*
72
+ - **inject view into dom**
71
73
  ```ts
72
74
  dom.in(".app").render(html`
73
75
  <h1>cool counter demo</h1>
74
76
  ${CounterView(1)}
75
77
  `)
76
78
  ```
77
- - ๐Ÿคฏ **register a view as a web component**
79
+ - ๐Ÿคฏ **register view as web component**
78
80
  ```ts
79
81
  dom.register({
80
82
  MyCounter: CounterView
81
83
  .component(BaseElement)
82
- .props(component => [dom.attrs(component).number.start ?? 0]),
84
+ .props(() => [1]),
83
85
  })
84
86
  ```
85
87
  ```html
86
- <my-counter start="1"></my-counter>
88
+ <my-counter></my-counter>
87
89
  ```
88
90
 
89
- ### ๐Ÿ‹ view declaration settings
90
- - special settings for views at declaration-time
91
+ ### ๐Ÿ‹ view settings
92
+ - lame settings for views you should know about
91
93
  ```ts
92
94
  export const CoolView = view
93
95
  .settings({mode: "open", delegatesFocus: true})
94
- .render(use => (greeting: string) => {
95
- return html`๐Ÿ˜Ž ${greeting} <slot></slot>`
96
- })
96
+ .render(use => (greeting: string) => html`๐Ÿ˜Ž ${greeting} <slot></slot>`)
97
97
  ```
98
98
  - all [attachShadow params](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#parameters) (like `mode` and `delegatesFocus`) are valid `settings`
99
99
  - note the `<slot></slot>` we'll use in the next example lol
100
100
 
101
- ### ๐Ÿ‹ view injection options
102
- - options for views at the template injection site
101
+ ### ๐Ÿ‹ view chain
102
+ - views have this sick chaining syntax for supplying more stuff at the template injection site
103
103
  ```ts
104
104
  dom.in(".app").render(html`
105
105
  <h2>cool example</h2>
106
- ${CoolView.props("hello")
106
+ ${CoolView
107
+ .props("hello")
107
108
  .attr("class", "hero")
108
109
  .children(html`<em>spongebob</em>`)
109
110
  .render()}
@@ -111,7 +112,7 @@ import {html, css} from "lit"
111
112
  ```
112
113
  - `props` โ€” provide props and start a view chain
113
114
  - `attr` โ€” set html attributes on the `<sly-view>` host element
114
- - `children` โ€” nested content in the host element, can be [slotted](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots)
115
+ - `children` โ€” add nested [slottable](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots) content
115
116
  - `render` โ€” end the view chain and render the lit directive
116
117
 
117
118
  ### ๐Ÿ‹ view/component universality
@@ -120,22 +121,23 @@ import {html, css} from "lit"
120
121
  export const GreeterView = view(use => (name: string) => {
121
122
  return html`<p>hello ${name}</p>`
122
123
  })
123
-
124
- // view usage:
125
- // GreeterView("pimsley")
126
124
  ```
127
- then convert it to a component.
125
+ - view usage
126
+ ```ts
127
+ GreeterView("pimsley")
128
+ ```
129
+ **then you can convert it to a component.**
128
130
  ```ts
129
131
  export class GreeterComponent extends (
130
132
  GreeterView
131
133
  .component(BaseElement)
132
134
  .props(component => [component.getAttribute("name") ?? "unknown"])
133
135
  ) {}
134
-
135
- // html usage:
136
- // <greeter-component name="pimsley"></greeter-component>
137
136
  ```
138
- - this trick with `class` and `extends` is amazing because typescript exports both the value of your component class, but also its type (doesn't work if you use `const`)
137
+ - html usage
138
+ ```html
139
+ <greeter-component name="pimsley"></greeter-component>
140
+ ```
139
141
  - **you can start with a component,**
140
142
  ```ts
141
143
  export class GreeterComponent extends (
@@ -145,44 +147,65 @@ import {html, css} from "lit"
145
147
  .component(BaseElement)
146
148
  .props(component => [component.getAttribute("name") ?? "unknown"])
147
149
  ) {}
148
-
149
- // html usage:
150
- // <greeter-component name="pimsley"></greeter-component>
151
- ```
152
- then it already has a `.view` ready for you.
153
- ```ts
154
- // view usage:
155
- // GreeterComponent.view("pimsley")
156
150
  ```
151
+ - html usage
152
+ ```html
153
+ <greeter-component name="pimsley"></greeter-component>
154
+ ```
155
+ **and it already has `.view` ready for you.**
156
+ - view usage
157
+ ```ts
158
+ GreeterComponent.view("pimsley")
159
+ ```
157
160
  - **understanding `.component(C)` and `.props(fn)`**
158
161
  - `.props` takes a fn that is called every render, which returns the props given to the view
159
162
  ```ts
160
- .component(BaseElement)
161
163
  .props(() => ["pimsley"])
162
164
  ```
163
165
  the props fn receives the component instance, so you can query html attributes or instance properties
164
166
  ```ts
165
- .component(BaseElement)
166
167
  .props(component => [component.getAttribute("name") ?? "unknown"])
167
168
  ```
168
- - `.component` accepts a subclass of `BaseElement`, which lets you define your own properties and methods for your component class
169
+ - `.component` accepts a subclass of `BaseElement`, so you can define your own properties and methods for your component class
169
170
  ```ts
170
- .component(class extends BaseElement {
171
- $name = signal("jim raynor")
172
- updateName(name: string) {
173
- this.$name.value = name
174
- }
175
- })
176
- .props(component => [component.$name.value])
171
+ const GreeterComponent = GreeterView
172
+
173
+ // declare your own custom class
174
+ .component(class extends BaseElement {
175
+ $name = signal("jim raynor")
176
+ updateName(name: string) {
177
+ this.$name.value = name
178
+ }
179
+ })
180
+
181
+ // props gets the right types on 'component'
182
+ .props(component => [component.$name.value])
177
183
  ```
178
- - `.component` lets devs interacting with your component get nice types
184
+ - `.component` provides the devs interacting with your component, with noice typings
179
185
  ```ts
180
- dom<GreeterComponent>("my-component").updateName("mortimer")
186
+ dom<GreeterComponent>("greeter-component").updateName("mortimer")
181
187
  ```
188
+ - typescript class wizardry
189
+ - โŒ smol-brain approach exports class value, but not the typings
190
+ ```ts
191
+ export const GreeterComponent = (...)
192
+ ```
193
+ - โœ… giga-brain approach exports class value AND the typings
194
+ ```ts
195
+ export class GreeterComponent extends (...) {}
196
+ ```
182
197
  - **register web components to the dom**
183
198
  ```ts
184
199
  dom.register({GreeterComponent})
185
200
  ```
201
+ - **oh and don't miss out on the insta-component shorthand**
202
+ ```ts
203
+ dom.register({
204
+ QuickComponent: view.component(use => html`โšก incredi`),
205
+ })
206
+ ```
207
+
208
+ <a id="use"></a>
186
209
 
187
210
  ### ๐Ÿ‹ "use" hooks reference
188
211
  - ๐Ÿ‘ฎ **follow the hooks rules**
@@ -328,7 +351,7 @@ import {BaseElement, Use, dom} from "@e280/sly"
328
351
  import {html, css} from "lit"
329
352
  ```
330
353
 
331
- `BaseElement` is an old-timey class-based "fogey" approach to making web components, but with a modern twist โ€” its `render` method gives you the same `use` hooks that views enjoy.
354
+ `BaseElement` is 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.
332
355
 
333
356
  ### ๐Ÿชต base element setup
334
357
  - **declare your element class**
@@ -337,7 +360,7 @@ import {html, css} from "lit"
337
360
  static styles = css`span{color:orange}`
338
361
 
339
362
  // custom property
340
- start = 10
363
+ $start = signal(10)
341
364
 
342
365
  // custom attributes
343
366
  attrs = dom.attrs(this).spec({
@@ -353,9 +376,9 @@ import {html, css} from "lit"
353
376
  const $count = use.signal(1)
354
377
  const increment = () => $count.value++
355
378
 
356
- const {start} = this
379
+ const {$start} = this
357
380
  const {multiply = 1} = this.attrs
358
- const result = start + (multiply * $count())
381
+ const result = $start() + (multiply * $count())
359
382
 
360
383
  return html`
361
384
  <span>${result}</span>
@@ -381,7 +404,7 @@ import {html, css} from "lit"
381
404
  const myElement = dom<MyElement>("my-element")
382
405
 
383
406
  // js property
384
- myElement.start = 100
407
+ myElement.$start(100)
385
408
 
386
409
  // html attributes
387
410
  myElement.attrs.multiply = 2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e280/sly",
3
- "version": "0.2.0-11",
3
+ "version": "0.2.0-12",
4
4
  "description": "web shadow views",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/x/index.html CHANGED
@@ -131,7 +131,7 @@ body {
131
131
  <img class=icon alt="" src="/assets/favicon.png"/>
132
132
  <h1>sly testing page</h1>
133
133
  <p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
134
- <p class=lil>v0.2.0-11</p>
134
+ <p class=lil>v0.2.0-12</p>
135
135
 
136
136
  <fastcount-element></fastcount-element>
137
137
  <counter-component start=280 step=2>component</counter-component>