@e280/sly 0.2.0-1 → 0.2.0-10

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 (183) hide show
  1. package/README.md +348 -60
  2. package/package.json +3 -3
  3. package/s/demo/demo.bundle.ts +9 -5
  4. package/s/demo/views/counter.ts +22 -24
  5. package/s/demo/views/demo.ts +10 -6
  6. package/s/demo/views/fastcount.ts +29 -0
  7. package/s/demo/views/loaders.ts +2 -2
  8. package/s/dom/attrs/attrs.ts +21 -0
  9. package/s/dom/attrs/parts/attr-fns.ts +38 -0
  10. package/s/dom/attrs/parts/attr-proxies.ts +35 -0
  11. package/s/dom/attrs/parts/attr-spec.ts +29 -0
  12. package/s/dom/attrs/parts/on-attrs.ts +8 -0
  13. package/s/dom/dom.ts +38 -16
  14. package/s/dom/{register.ts → parts/register.ts} +2 -7
  15. package/s/dom/types.ts +39 -2
  16. package/s/index.html.ts +4 -2
  17. package/s/index.ts +10 -8
  18. package/s/loot/drag-and-drops.ts +82 -0
  19. package/s/loot/drops.ts +35 -0
  20. package/s/loot/helpers.ts +31 -0
  21. package/s/loot/index.ts +5 -0
  22. package/s/ops/loaders/make-loader.ts +3 -3
  23. package/s/ops/loaders/parts/anims.ts +1 -1
  24. package/s/ops/loaders/parts/ascii-anim.ts +3 -3
  25. package/s/ops/loaders/parts/error-display.ts +2 -2
  26. package/s/ops/op.ts +2 -2
  27. package/s/{views → ui/base}/use.ts +19 -19
  28. package/s/ui/base/utils/attr-watcher.ts +22 -0
  29. package/s/ui/base/utils/reactor.ts +21 -0
  30. package/s/ui/base-element.ts +76 -0
  31. package/s/ui/types.ts +33 -0
  32. package/s/ui/view/make-component.ts +33 -0
  33. package/s/ui/view/make-view.ts +40 -0
  34. package/s/{views/utils → ui/view/parts}/apply-attrs.ts +4 -7
  35. package/s/ui/view/parts/capsule.ts +67 -0
  36. package/s/ui/view/parts/chain.ts +33 -0
  37. package/s/ui/view/parts/context.ts +10 -0
  38. package/s/ui/view/parts/directive.ts +29 -0
  39. package/s/ui/view/parts/sly-view.ts +15 -0
  40. package/s/ui/view.ts +24 -0
  41. package/x/demo/demo.bundle.js +8 -4
  42. package/x/demo/demo.bundle.js.map +1 -1
  43. package/x/demo/demo.bundle.min.js +19 -22
  44. package/x/demo/demo.bundle.min.js.map +4 -4
  45. package/x/demo/views/counter.d.ts +374 -1
  46. package/x/demo/views/counter.js +19 -22
  47. package/x/demo/views/counter.js.map +1 -1
  48. package/x/demo/views/demo.d.ts +4 -1
  49. package/x/demo/views/demo.js +10 -5
  50. package/x/demo/views/demo.js.map +1 -1
  51. package/x/demo/views/fastcount.d.ts +12 -0
  52. package/x/demo/views/fastcount.js +21 -0
  53. package/x/demo/views/fastcount.js.map +1 -0
  54. package/x/demo/views/loaders.js +2 -2
  55. package/x/demo/views/loaders.js.map +1 -1
  56. package/x/dom/attrs/attrs.d.ts +20 -0
  57. package/x/dom/attrs/attrs.js +17 -0
  58. package/x/dom/attrs/attrs.js.map +1 -0
  59. package/x/dom/attrs/parts/attr-fns.d.ts +13 -0
  60. package/x/dom/attrs/parts/attr-fns.js +42 -0
  61. package/x/dom/attrs/parts/attr-fns.js.map +1 -0
  62. package/x/dom/attrs/parts/attr-proxies.d.ts +8 -0
  63. package/x/dom/attrs/parts/attr-proxies.js +21 -0
  64. package/x/dom/attrs/parts/attr-proxies.js.map +1 -0
  65. package/x/dom/attrs/parts/attr-spec.d.ts +3 -0
  66. package/x/dom/attrs/parts/attr-spec.js +21 -0
  67. package/x/dom/attrs/parts/attr-spec.js.map +1 -0
  68. package/x/dom/attrs/parts/on-attrs.d.ts +2 -0
  69. package/x/dom/attrs/parts/on-attrs.js +7 -0
  70. package/x/dom/attrs/parts/on-attrs.js.map +1 -0
  71. package/x/dom/dom.d.ts +18 -7
  72. package/x/dom/dom.js +25 -12
  73. package/x/dom/dom.js.map +1 -1
  74. package/x/dom/parts/dashify.js.map +1 -0
  75. package/x/dom/{register.d.ts → parts/register.d.ts} +2 -6
  76. package/x/dom/parts/register.js.map +1 -0
  77. package/x/dom/types.d.ts +14 -2
  78. package/x/index.d.ts +9 -7
  79. package/x/index.html +6 -4
  80. package/x/index.html.js +4 -2
  81. package/x/index.html.js.map +1 -1
  82. package/x/index.js +9 -7
  83. package/x/index.js.map +1 -1
  84. package/x/loot/drag-and-drops.d.ts +30 -0
  85. package/x/loot/drag-and-drops.js +63 -0
  86. package/x/loot/drag-and-drops.js.map +1 -0
  87. package/x/loot/drops.d.ts +14 -0
  88. package/x/loot/drops.js +25 -0
  89. package/x/loot/drops.js.map +1 -0
  90. package/x/loot/helpers.d.ts +3 -0
  91. package/x/loot/helpers.js +21 -0
  92. package/x/loot/helpers.js.map +1 -0
  93. package/x/loot/index.d.ts +3 -0
  94. package/x/loot/index.js +4 -0
  95. package/x/loot/index.js.map +1 -0
  96. package/x/ops/loaders/make-loader.d.ts +1 -1
  97. package/x/ops/loaders/make-loader.js +2 -2
  98. package/x/ops/loaders/make-loader.js.map +1 -1
  99. package/x/ops/loaders/parts/anims.d.ts +1 -1
  100. package/x/ops/loaders/parts/ascii-anim.d.ts +2 -2
  101. package/x/ops/loaders/parts/ascii-anim.js +2 -2
  102. package/x/ops/loaders/parts/ascii-anim.js.map +1 -1
  103. package/x/ops/loaders/parts/error-display.js +2 -2
  104. package/x/ops/loaders/parts/error-display.js.map +1 -1
  105. package/x/ops/op.d.ts +2 -2
  106. package/x/ops/op.js +2 -2
  107. package/x/ops/op.js.map +1 -1
  108. package/x/ui/base/css-reset.js.map +1 -0
  109. package/x/{views → ui/base}/use.d.ts +6 -6
  110. package/x/{views → ui/base}/use.js +10 -12
  111. package/x/ui/base/use.js.map +1 -0
  112. package/x/ui/base/utils/apply-styles.js.map +1 -0
  113. package/x/ui/base/utils/attr-watcher.d.ts +8 -0
  114. package/x/ui/base/utils/attr-watcher.js +20 -0
  115. package/x/ui/base/utils/attr-watcher.js.map +1 -0
  116. package/x/ui/base/utils/mounts.js.map +1 -0
  117. package/x/ui/base/utils/reactor.d.ts +5 -0
  118. package/x/ui/base/utils/reactor.js +17 -0
  119. package/x/ui/base/utils/reactor.js.map +1 -0
  120. package/x/ui/base-element.d.ts +19 -0
  121. package/x/ui/base-element.js +52 -0
  122. package/x/ui/base-element.js.map +1 -0
  123. package/x/ui/types.d.ts +20 -0
  124. package/x/{views → ui}/types.js.map +1 -1
  125. package/x/ui/view/make-component.d.ts +5 -0
  126. package/x/ui/view/make-component.js +16 -0
  127. package/x/ui/view/make-component.js.map +1 -0
  128. package/x/ui/view/make-view.d.ts +2 -0
  129. package/x/ui/view/make-view.js +16 -0
  130. package/x/ui/view/make-view.js.map +1 -0
  131. package/x/ui/view/parts/apply-attrs.d.ts +2 -0
  132. package/x/{views/utils → ui/view/parts}/apply-attrs.js +2 -4
  133. package/x/ui/view/parts/apply-attrs.js.map +1 -0
  134. package/x/ui/view/parts/capsule.d.ts +13 -0
  135. package/x/ui/view/parts/capsule.js +49 -0
  136. package/x/ui/view/parts/capsule.js.map +1 -0
  137. package/x/ui/view/parts/chain.d.ts +11 -0
  138. package/x/ui/view/parts/chain.js +21 -0
  139. package/x/ui/view/parts/chain.js.map +1 -0
  140. package/x/ui/view/parts/context.d.ts +8 -0
  141. package/x/ui/view/parts/context.js +10 -0
  142. package/x/ui/view/parts/context.js.map +1 -0
  143. package/x/ui/view/parts/directive.d.ts +5 -0
  144. package/x/ui/view/parts/directive.js +18 -0
  145. package/x/ui/view/parts/directive.js.map +1 -0
  146. package/x/ui/view/parts/sly-view.d.ts +5 -0
  147. package/x/ui/view/parts/sly-view.js +13 -0
  148. package/x/ui/view/parts/sly-view.js.map +1 -0
  149. package/x/ui/view.d.ts +11 -0
  150. package/x/ui/view.js +15 -0
  151. package/x/ui/view.js.map +1 -0
  152. package/s/views/attributes.ts +0 -89
  153. package/s/views/types.ts +0 -40
  154. package/s/views/view.ts +0 -150
  155. package/x/dom/dashify.js.map +0 -1
  156. package/x/dom/register.js.map +0 -1
  157. package/x/views/attributes.d.ts +0 -10
  158. package/x/views/attributes.js +0 -46
  159. package/x/views/attributes.js.map +0 -1
  160. package/x/views/css-reset.js.map +0 -1
  161. package/x/views/types.d.ts +0 -31
  162. package/x/views/use.js.map +0 -1
  163. package/x/views/utils/apply-attrs.d.ts +0 -2
  164. package/x/views/utils/apply-attrs.js.map +0 -1
  165. package/x/views/utils/apply-styles.js.map +0 -1
  166. package/x/views/utils/mounts.js.map +0 -1
  167. package/x/views/view.d.ts +0 -9
  168. package/x/views/view.js +0 -116
  169. package/x/views/view.js.map +0 -1
  170. /package/s/dom/{dashify.ts → parts/dashify.ts} +0 -0
  171. /package/s/{views → ui/base}/css-reset.ts +0 -0
  172. /package/s/{views → ui/base}/utils/apply-styles.ts +0 -0
  173. /package/s/{views → ui/base}/utils/mounts.ts +0 -0
  174. /package/x/dom/{dashify.d.ts → parts/dashify.d.ts} +0 -0
  175. /package/x/dom/{dashify.js → parts/dashify.js} +0 -0
  176. /package/x/dom/{register.js → parts/register.js} +0 -0
  177. /package/x/{views → ui/base}/css-reset.d.ts +0 -0
  178. /package/x/{views → ui/base}/css-reset.js +0 -0
  179. /package/x/{views → ui/base}/utils/apply-styles.d.ts +0 -0
  180. /package/x/{views → ui/base}/utils/apply-styles.js +0 -0
  181. /package/x/{views → ui/base}/utils/mounts.d.ts +0 -0
  182. /package/x/{views → ui/base}/utils/mounts.js +0 -0
  183. /package/x/{views → ui}/types.js +0 -0
@@ -1,24 +1,28 @@
1
1
 
2
2
  import {css, html} from "lit"
3
- import {view} from "../../views/view.js"
3
+
4
+ import {view} from "../../ui/view.js"
4
5
  import {CounterView} from "./counter.js"
5
6
  import {LoadersView} from "./loaders.js"
6
- import {cssReset} from "../../views/css-reset.js"
7
+ import {cssReset} from "../../ui/base/css-reset.js"
7
8
 
8
- export const DemoView = view(use => () => {
9
+ export class DemoComponent extends (view.component(use => {
9
10
  use.name("demo")
10
11
  use.styles(cssReset, styles)
11
-
12
12
  return html`
13
- ${CounterView.props(2).children("view").render()}
13
+ ${CounterView
14
+ .props(768, 3)
15
+ .children("view")
16
+ .render()}
14
17
  ${LoadersView()}
15
18
  `
16
- })
19
+ })) {}
17
20
 
18
21
  const styles = css`
19
22
  :host {
20
23
  display: flex;
21
24
  flex-direction: column;
25
+ align-items: center;
22
26
  gap: 1em;
23
27
  }
24
28
  `
@@ -0,0 +1,29 @@
1
+
2
+ import {css, html} from "lit"
3
+ import {nap, repeat} from "@e280/stz"
4
+
5
+ import {dom} from "../../dom/dom.js"
6
+ import {Use} from "../../ui/base/use.js"
7
+ import {BaseElement} from "../../ui/base-element.js"
8
+
9
+ export class FastcountElement extends BaseElement {
10
+ static styles = css`span{color:orange}`
11
+
12
+ attrs = dom.attrs(this).spec({value: Number})
13
+ something = {whatever: "rofl"}
14
+
15
+ render(use: Use) {
16
+ const {value = 1} = this.attrs
17
+ const $count = use.signal(0)
18
+
19
+ use.mount(() => repeat(async() => {
20
+ await nap(10)
21
+ await $count($count() + 1)
22
+ }))
23
+
24
+ return html`
25
+ <span>${$count() * value}</span>
26
+ `
27
+ }
28
+ }
29
+
@@ -1,8 +1,8 @@
1
1
 
2
2
  import {css, html} from "lit"
3
3
  import {Op} from "../../ops/op.js"
4
- import {view} from "../../views/view.js"
5
- import {cssReset} from "../../views/css-reset.js"
4
+ import {view} from "../../ui/view.js"
5
+ import {cssReset} from "../../ui/base/css-reset.js"
6
6
  import {anims, makeLoader} from "../../ops/loaders/make-loader.js"
7
7
 
8
8
  export const LoadersView = view(use => () => {
@@ -0,0 +1,21 @@
1
+
2
+ import {AttrSpec} from "../types.js"
3
+ import {onAttrs} from "./parts/on-attrs.js"
4
+ import {attrFns} from "./parts/attr-fns.js"
5
+ import {attrSpec} from "./parts/attr-spec.js"
6
+ import {AttrProxies} from "./parts/attr-proxies.js"
7
+
8
+ export function attrs(element: HTMLElement) {
9
+ const proxies = new AttrProxies(element)
10
+ return {
11
+ string: proxies.string,
12
+ number: proxies.number,
13
+ boolean: proxies.boolean,
14
+ on: (fn: () => void) => onAttrs(element, fn),
15
+ spec: <A extends AttrSpec>(spec: A) => attrSpec(element, spec),
16
+ }
17
+ }
18
+
19
+ attrs.get = attrFns.get
20
+ attrs.set = attrFns.set
21
+
@@ -0,0 +1,38 @@
1
+
2
+ /** fns for getting and setting html attributes of various types */
3
+ export const attrFns = {
4
+ get: {
5
+ string: (e: HTMLElement, key: string) => {
6
+ return e.getAttribute(key) ?? undefined
7
+ },
8
+ number: (e: HTMLElement, key: string) => {
9
+ const raw = e.getAttribute(key)
10
+ return (raw === null || !raw)
11
+ ? undefined
12
+ : Number(raw)
13
+ },
14
+ boolean: (e: HTMLElement, key: string) => {
15
+ const raw = e.getAttribute(key)
16
+ return raw !== null
17
+ },
18
+ },
19
+
20
+ set: {
21
+ string: (e: HTMLElement, key: string, value: string | undefined) => {
22
+ if (value === undefined) e.removeAttribute(key)
23
+ else e.setAttribute(key, value)
24
+ return true
25
+ },
26
+ number: (e: HTMLElement, key: string, value: number | undefined) => {
27
+ if (value === undefined) e.removeAttribute(key)
28
+ else e.setAttribute(key, value.toString())
29
+ return true
30
+ },
31
+ boolean: (e: HTMLElement, key: string, value: boolean | undefined) => {
32
+ if (value) e.setAttribute(key, "")
33
+ else e.removeAttribute(key)
34
+ return true
35
+ },
36
+ },
37
+ }
38
+
@@ -0,0 +1,35 @@
1
+
2
+ import {attrFns} from "./attr-fns.js"
3
+
4
+ /** a typed proxy accessor for html attributes */
5
+ export class AttrProxies {
6
+ constructor(public element: HTMLElement) {}
7
+
8
+ string = new Proxy({}, {
9
+ get: (_t, key: string) => (
10
+ attrFns.get.string(this.element, key)
11
+ ),
12
+ set: (_t, key: string, value: string | undefined) => (
13
+ attrFns.set.string(this.element, key, value)
14
+ ),
15
+ }) as Record<string, string | undefined>
16
+
17
+ number = new Proxy({}, {
18
+ get: (_t, key: string) => (
19
+ attrFns.get.number(this.element, key)
20
+ ),
21
+ set: (_t, key: string, value: number | undefined) => (
22
+ attrFns.set.number(this.element, key, value)
23
+ ),
24
+ }) as Record<string, number | undefined>
25
+
26
+ boolean = new Proxy({}, {
27
+ get: (_t, key: string) => (
28
+ attrFns.get.boolean(this.element, key)
29
+ ),
30
+ set: (_t, key: string, value: boolean | undefined) => (
31
+ attrFns.set.boolean(this.element, key, value)
32
+ ),
33
+ }) as Record<string, boolean | undefined>
34
+ }
35
+
@@ -0,0 +1,29 @@
1
+
2
+ import {AttrSpec, AttrTypes} from "../../types.js"
3
+ import {attrFns} from "./attr-fns.js"
4
+
5
+ /** specify available html attributes and their types and create a proxy accessor */
6
+ export const attrSpec = <A extends AttrSpec>(
7
+ e: HTMLElement,
8
+ spec: A,
9
+ ) => new Proxy(spec, {
10
+
11
+ get: (_target, key: string) => {
12
+ switch (spec[key]) {
13
+ case String: return attrFns.get.string(e, key)
14
+ case Number: return attrFns.get.number(e, key)
15
+ case Boolean: return attrFns.get.boolean(e, key)
16
+ default: throw new Error(`invalid attribute type for "${key}"`)
17
+ }
18
+ },
19
+
20
+ set: (_target, key: string, value: any) => {
21
+ switch (spec[key]) {
22
+ case String: return attrFns.set.string(e, key, value)
23
+ case Number: return attrFns.set.number(e, key, value)
24
+ case Boolean: return attrFns.set.boolean(e, key, value)
25
+ default: throw new Error(`invalid attribute type for "${key}"`)
26
+ }
27
+ },
28
+ }) as any as AttrTypes<A>
29
+
@@ -0,0 +1,8 @@
1
+
2
+ /** respond when any attribute changes on the html element */
3
+ export function onAttrs(element: HTMLElement, fn: () => void) {
4
+ const observer = new MutationObserver(fn)
5
+ observer.observe(element, {attributes: true})
6
+ return () => observer.disconnect()
7
+ }
8
+
package/s/dom/dom.ts CHANGED
@@ -1,23 +1,36 @@
1
1
 
2
2
  import {render} from "lit"
3
- import {register} from "./register.js"
4
- import {Content} from "../views/types.js"
5
- import {Queryable, Renderable} from "./types.js"
3
+ import {AttrSpec} from "./types.js"
4
+ import {attrs} from "./attrs/attrs.js"
5
+ import {Content} from "../ui/types.js"
6
+ import {register} from "./parts/register.js"
7
+
8
+ export type Renderable = HTMLElement | ShadowRoot | DocumentFragment
9
+ export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment
10
+
11
+ function require<E extends Element>(
12
+ container: Queryable,
13
+ selector: string,
14
+ ) {
15
+ const e = container.querySelector<E>(selector)
16
+ if (!e) throw new Error(`element not found (${selector})`)
17
+ return e
18
+ }
6
19
 
7
20
  export class Dom<C extends Queryable> {
8
21
  constructor(public element: C) {}
9
22
 
10
- in<E extends HTMLElement>(elementOrSelector: E | string) {
11
- return new Dom(
12
- typeof elementOrSelector === "string"
13
- ? this.require<E>(elementOrSelector)
14
- : elementOrSelector
23
+ in<E extends HTMLElement>(selectorOrElement: string | E) {
24
+ return new Dom<E>(
25
+ (typeof selectorOrElement === "string")
26
+ ? require(this.element, selectorOrElement) as E
27
+ : selectorOrElement
15
28
  )
16
29
  }
17
30
 
18
31
  require<E extends Element = HTMLElement>(selector: string) {
19
32
  const e = this.element.querySelector<E>(selector)
20
- if (!e) throw new Error(`$1 ${selector} not found`)
33
+ if (!e) throw new Error(`element not found (${selector})`)
21
34
  return e
22
35
  }
23
36
 
@@ -32,20 +45,29 @@ export class Dom<C extends Queryable> {
32
45
  render(...content: Content[]) {
33
46
  return render(content, this.element as Renderable)
34
47
  }
35
- }
36
48
 
37
- export function dom(selector: string) {
38
- return new Dom(document).require(selector)
49
+ attrs() {
50
+ return attrs(this.element as HTMLElement)
51
+ }
39
52
  }
40
53
 
41
- const doc = new Dom(document)
42
- dom.register = register
43
- dom.render = (container: Renderable, ...content: Content[]) => {
44
- return render(content, container)
54
+ export function dom<E extends Queryable>(selector: string): E
55
+ export function dom<E extends Queryable>(element: E): Dom<E>
56
+ export function dom<E extends Queryable>(selectorOrElement: string | E): E | Dom<E> {
57
+ return (typeof selectorOrElement === "string")
58
+ ? require(document, selectorOrElement) as E
59
+ : new Dom(selectorOrElement)
45
60
  }
46
61
 
62
+ const doc = new Dom(document)
47
63
  dom.in = doc.in.bind(doc)
48
64
  dom.require = doc.require.bind(doc)
49
65
  dom.maybe = doc.maybe.bind(doc)
50
66
  dom.all = doc.all.bind(doc)
51
67
 
68
+ dom.attrs = attrs
69
+ dom.register = register
70
+ dom.render = (container: Renderable, ...content: Content[]) => {
71
+ return render(content, container)
72
+ }
73
+
@@ -1,11 +1,6 @@
1
1
 
2
2
  import {dashify} from "./dashify.js"
3
- import {HTMLElementClasses} from "./types.js"
4
-
5
- export type RegistrationOptions = {
6
- soft: boolean
7
- upgrade: boolean
8
- }
3
+ import {HTMLElementClasses, RegisterOptions} from "../types.js"
9
4
 
10
5
  /**
11
6
  * register custom elements (web components) to the dom
@@ -21,7 +16,7 @@ export type RegistrationOptions = {
21
16
  */
22
17
  export function register<E extends HTMLElementClasses>(
23
18
  elements: E,
24
- options: Partial<RegistrationOptions> = {},
19
+ options: Partial<RegisterOptions> = {},
25
20
  ) {
26
21
 
27
22
  const {
package/s/dom/types.ts CHANGED
@@ -1,8 +1,45 @@
1
1
 
2
- export type Renderable = HTMLElement | ShadowRoot | DocumentFragment
3
- export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment
2
+ import {attrs} from "./attrs/attrs.js"
3
+
4
+ // attrs
5
+
6
+ export type AttrKind = (
7
+ | typeof String
8
+ | typeof Number
9
+ | typeof Boolean
10
+ )
11
+
12
+ export type AttrType<H extends AttrKind> = (
13
+ H extends typeof String
14
+ ? string | undefined
15
+
16
+ : H extends typeof Number
17
+ ? number | undefined
18
+
19
+ : H extends typeof Boolean
20
+ ? boolean
21
+
22
+ : never
23
+ )
24
+
25
+ export type AttrSpec = {
26
+ [key: string]: AttrKind
27
+ }
28
+
29
+ export type AttrTypes<A extends AttrSpec> = {
30
+ [P in keyof A]: AttrType<A[P]>
31
+ }
32
+
33
+ export type Attrs = ReturnType<typeof attrs>
34
+
35
+ // register
4
36
 
5
37
  export type HTMLElementClasses = {
6
38
  [key: string]: {new(...args: any[]): HTMLElement}
7
39
  }
8
40
 
41
+ export type RegisterOptions = {
42
+ soft: boolean
43
+ upgrade: boolean
44
+ }
45
+
package/s/index.html.ts CHANGED
@@ -29,8 +29,10 @@ export default ssg.page(import.meta.url, async orb => ({
29
29
  <h1>sly testing page</h1>
30
30
  <p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
31
31
  <p class=lil>v${orb.packageVersion()}</p>
32
- <demo-counter>component</demo-counter>
33
- <div class=demo></div>
32
+
33
+ <fastcount-element></fastcount-element>
34
+ <counter-component start=280 step=2>component</counter-component>
35
+ <demo-component></demo-component>
34
36
  `,
35
37
  }))
36
38
 
package/s/index.ts CHANGED
@@ -1,19 +1,21 @@
1
1
 
2
- export * from "./dom/dashify.js"
3
- export * from "./dom/register.js"
4
2
  export * from "./dom/types.js"
3
+ export * from "./dom/dom.js"
5
4
 
6
5
  export * from "./ops/loaders/make-loader.js"
7
6
  export * from "./ops/loaders/parts/ascii-anim.js"
8
7
  export * from "./ops/loaders/parts/error-display.js"
9
-
10
8
  export * from "./ops/op.js"
11
9
  export * from "./ops/podium.js"
12
10
  export * from "./ops/types.js"
13
11
 
14
- export * from "./views/attributes.js"
15
- export * from "./views/css-reset.js"
16
- export * from "./views/types.js"
17
- export * from "./views/use.js"
18
- export * from "./views/view.js"
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"
19
21
 
@@ -0,0 +1,82 @@
1
+
2
+ import {signal} from "@e280/strata"
3
+ import {Drops} from "./drops.js"
4
+ import {outsideCurrentTarget} from "./helpers.js"
5
+
6
+ /** respond to user dragging-and-dropping things around on a webpage */
7
+ export class DragAndDrops<Draggy, Droppy> {
8
+
9
+ /** what is currently being dragged */
10
+ $draggy = signal<Draggy | undefined>(undefined)
11
+
12
+ /** what dropzone are we curently hovering over */
13
+ $droppy = signal<Droppy | undefined>(undefined)
14
+
15
+ constructor(private params: {
16
+
17
+ /** accept a dropped item that was declared within this system */
18
+ acceptDrop: (event: DragEvent, draggy: Draggy, droppy: Droppy) => void
19
+
20
+ /** also accept drops on the side */
21
+ backchannelDrops?: Drops
22
+ }) {}
23
+
24
+ get dragging() {
25
+ return this.$draggy()
26
+ }
27
+
28
+ get hovering() {
29
+ return this.$droppy()
30
+ }
31
+
32
+ /** make event listeners to attach to your dragzone(s) */
33
+ dragzone = (getDraggy: () => Draggy) => ({
34
+ draggable: "true",
35
+
36
+ dragstart: (_: DragEvent) => {
37
+ this.$draggy.value = getDraggy()
38
+ },
39
+
40
+ dragend: (_: DragEvent) => {
41
+ this.$draggy.value = undefined
42
+ this.$droppy.value = undefined
43
+ },
44
+ })
45
+
46
+ /** make event listeners to attach to your dropzones(s) */
47
+ dropzone = (getDroppy: () => Droppy) => ({
48
+ dragenter: (_: DragEvent) => {},
49
+
50
+ dragover: (event: DragEvent) => {
51
+ event.preventDefault()
52
+ if (this.$draggy())
53
+ this.$droppy.value = getDroppy()
54
+ else
55
+ this.params.backchannelDrops?.dragover(event)
56
+ },
57
+
58
+ dragleave: (event: DragEvent) => {
59
+ if (outsideCurrentTarget(event))
60
+ this.$droppy.value = undefined
61
+ this.params.backchannelDrops?.dragleave(event)
62
+ },
63
+
64
+ drop: (event: DragEvent) => {
65
+ event.preventDefault()
66
+ const {acceptDrop} = this.params
67
+ const draggy = this.$draggy()
68
+ const droppy = this.$droppy()
69
+ try {
70
+ if (draggy && droppy)
71
+ acceptDrop(event, draggy, droppy)
72
+ else
73
+ this.params.backchannelDrops?.drop(event)
74
+ }
75
+ finally {
76
+ this.$draggy.value = undefined
77
+ this.$droppy.value = undefined
78
+ }
79
+ },
80
+ })
81
+ }
82
+
@@ -0,0 +1,35 @@
1
+
2
+ import {signal} from "@e280/strata"
3
+ import {outsideCurrentTarget} from "./helpers.js"
4
+
5
+ /** dropzone that accepts user-dropped stuff like files */
6
+ export class Drops {
7
+ $indicator = signal(false)
8
+
9
+ constructor(private params: {
10
+
11
+ /** whether or not the dragged item is acceptable for a drop */
12
+ predicate: (event: DragEvent) => boolean
13
+
14
+ /** fn to handle the drop of an acceptable item */
15
+ acceptDrop: (event: DragEvent) => void
16
+ }) {}
17
+
18
+ dragover = (event: DragEvent) => {
19
+ event.preventDefault()
20
+ this.$indicator.value = this.params.predicate(event)
21
+ }
22
+
23
+ dragleave = (event: DragEvent) => {
24
+ if (outsideCurrentTarget(event))
25
+ this.$indicator.value = false
26
+ }
27
+
28
+ drop = (event: DragEvent) => {
29
+ event.preventDefault()
30
+ this.$indicator.value = false
31
+ if (this.params.predicate(event))
32
+ this.params.acceptDrop(event)
33
+ }
34
+ }
35
+
@@ -0,0 +1,31 @@
1
+
2
+ export function hasFiles(event: DragEvent) {
3
+ return !!(
4
+ event.dataTransfer &&
5
+ event.dataTransfer.types.includes("Files")
6
+ )
7
+ }
8
+
9
+ export function files(event: DragEvent) {
10
+ return event.dataTransfer
11
+ ? Array.from(event.dataTransfer.files)
12
+ : []
13
+ }
14
+
15
+ export function outsideCurrentTarget(event: DragEvent) {
16
+ const isCursorOutsideViewport = !event.relatedTarget || (
17
+ event.clientX === 0 &&
18
+ event.clientY === 0
19
+ )
20
+
21
+ if (isCursorOutsideViewport)
22
+ return true
23
+
24
+ const rect = (event.currentTarget as any).getBoundingClientRect()
25
+ const withinX = event.clientX >= rect.left && event.clientX <= rect.right
26
+ const withinY = event.clientY >= rect.top && event.clientY <= rect.bottom
27
+ const cursorOutsideCurrentTarget = !(withinX && withinY)
28
+
29
+ return cursorOutsideCurrentTarget
30
+ }
31
+
@@ -0,0 +1,5 @@
1
+
2
+ export * from "./drag-and-drops.js"
3
+ export * from "./drops.js"
4
+ export * from "./helpers.js"
5
+
@@ -1,7 +1,7 @@
1
1
 
2
2
  import {Op} from "../op.js"
3
- import {braille} from "./parts/anims.js"
4
- import {Content} from "../../views/types.js"
3
+ import {earth} from "./parts/anims.js"
4
+ import {Content} from "../../ui/types.js"
5
5
  import {ErrorDisplay} from "./parts/error-display.js"
6
6
 
7
7
  export * as anims from "./parts/anims.js"
@@ -9,7 +9,7 @@ export * as anims from "./parts/anims.js"
9
9
  export type Loader = <V>(op: Op<V>, ready: (value: V) => Content) => Content
10
10
 
11
11
  export function makeLoader(
12
- loading: () => Content = braille,
12
+ loading: () => Content = earth,
13
13
  error: (error: any) => Content = (error: any) => ErrorDisplay(error),
14
14
  ): Loader {
15
15
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  import {makeAsciiAnim} from "./ascii-anim.js"
3
- import {Content} from "../../../views/types.js"
3
+ import {Content} from "../../../ui/types.js"
4
4
 
5
5
  const fast = 20
6
6
  const mid = 10
@@ -2,9 +2,9 @@
2
2
  import {css} from "lit"
3
3
  import {nap, repeat} from "@e280/stz"
4
4
 
5
- import {view} from "../../../views/view.js"
6
- import {Content} from "../../../views/types.js"
7
- import {cssReset} from "../../../views/css-reset.js"
5
+ import {view} from "../../../ui/view.js"
6
+ import {Content} from "../../../ui/types.js"
7
+ import {cssReset} from "../../../ui/base/css-reset.js"
8
8
 
9
9
  export function makeAsciiAnim(hz: number, frames: string[]): () => Content {
10
10
  return () => AsciiAnim({hz, frames})
@@ -1,7 +1,7 @@
1
1
 
2
2
  import {css, html} from "lit"
3
- import {view} from "../../../views/view.js"
4
- import {cssReset} from "../../../views/css-reset.js"
3
+ import {view} from "../../../ui/view.js"
4
+ import {cssReset} from "../../../ui/base/css-reset.js"
5
5
 
6
6
  export const ErrorDisplay = view(use => (error: any) => {
7
7
  use.name("error")
package/s/ops/op.ts CHANGED
@@ -16,7 +16,7 @@ export class Op<V> {
16
16
  return op
17
17
  }
18
18
 
19
- static fn<V>(fn: () => Promise<V>) {
19
+ static load<V>(fn: () => Promise<V>) {
20
20
  return this.promise(fn())
21
21
  }
22
22
 
@@ -74,7 +74,7 @@ export class Op<V> {
74
74
  }
75
75
  }
76
76
 
77
- async fn(fn: () => Promise<V>) {
77
+ async load(fn: () => Promise<V>) {
78
78
  return this.promise(fn())
79
79
  }
80
80