@tempots/dom 5.0.0 → 5.0.1

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 (191) hide show
  1. package/dist/clean.d.ts +2 -0
  2. package/dist/clean.js +1 -0
  3. package/dist/components/Attribute.d.ts +15 -0
  4. package/dist/components/Attribute.js +16 -0
  5. package/dist/components/BooleanAttribute.d.ts +15 -0
  6. package/dist/components/BooleanAttribute.js +16 -0
  7. package/dist/components/ClassName.d.ts +13 -0
  8. package/dist/components/ClassName.js +14 -0
  9. package/dist/components/El.d.ts +15 -0
  10. package/dist/components/El.js +21 -0
  11. package/dist/components/FadeIn.d.ts +18 -0
  12. package/dist/components/FadeIn.js +52 -0
  13. package/dist/components/FadeOut.d.ts +16 -0
  14. package/dist/components/FadeOut.js +39 -0
  15. package/dist/components/For.d.ts +7 -0
  16. package/dist/components/For.js +15 -0
  17. package/dist/components/Fragment.d.ts +12 -0
  18. package/dist/components/Fragment.js +16 -0
  19. package/dist/components/HiddenWhenEmpty.d.ts +7 -0
  20. package/dist/components/HiddenWhenEmpty.js +12 -0
  21. package/dist/components/If.d.ts +14 -0
  22. package/dist/components/If.js +19 -0
  23. package/dist/components/InnerHTML.d.ts +13 -0
  24. package/dist/components/InnerHTML.js +23 -0
  25. package/dist/components/Lifecycle.d.ts +14 -0
  26. package/dist/components/Lifecycle.js +18 -0
  27. package/dist/components/Match.d.ts +33 -0
  28. package/dist/components/Match.js +44 -0
  29. package/dist/components/NotEmpty.d.ts +10 -0
  30. package/dist/components/NotEmpty.js +11 -0
  31. package/dist/components/On.d.ts +15 -0
  32. package/dist/components/On.js +14 -0
  33. package/dist/components/OnRemove.d.ts +11 -0
  34. package/dist/components/OnRemove.js +14 -0
  35. package/dist/components/OneOf.d.ts +20 -0
  36. package/dist/components/OneOf.js +45 -0
  37. package/dist/components/Portal.d.ts +15 -0
  38. package/dist/components/Portal.js +20 -0
  39. package/dist/components/Property.d.ts +15 -0
  40. package/dist/components/Property.js +16 -0
  41. package/dist/components/Provider.d.ts +28 -0
  42. package/dist/components/Provider.js +44 -0
  43. package/dist/components/Repeat.d.ts +15 -0
  44. package/dist/components/Repeat.js +33 -0
  45. package/dist/components/Shadow.d.ts +0 -0
  46. package/dist/components/Shadow.js +1 -0
  47. package/dist/components/Show.d.ts +20 -0
  48. package/dist/components/Show.js +22 -0
  49. package/dist/components/Text.d.ts +15 -0
  50. package/dist/components/Text.js +33 -0
  51. package/dist/components/TextContent.d.ts +13 -0
  52. package/dist/components/TextContent.js +23 -0
  53. package/dist/components/Tween.d.ts +75 -0
  54. package/dist/components/Tween.js +242 -0
  55. package/dist/components/animatable.d.ts +53 -0
  56. package/dist/components/animatable.js +156 -0
  57. package/dist/dom-context.d.ts +38 -0
  58. package/dist/dom-context.js +260 -0
  59. package/dist/helpers/handle-anchor-click.d.ts +4 -0
  60. package/dist/helpers/handle-anchor-click.js +43 -0
  61. package/dist/helpers/handle-text-input.d.ts +1 -0
  62. package/dist/helpers/handle-text-input.js +4 -0
  63. package/dist/helpers/is-empty-element.d.ts +2 -0
  64. package/dist/helpers/is-empty-element.js +8 -0
  65. package/dist/index.d.ts +36 -0
  66. package/dist/jsx-dev-runtime.d.ts +1 -0
  67. package/dist/jsx-dev-runtime.js +1 -0
  68. package/dist/jsx-runtime.d.ts +9 -0
  69. package/dist/jsx-runtime.js +157 -0
  70. package/dist/jsx.d.ts +806 -0
  71. package/dist/jsx.js +1 -0
  72. package/dist/prop.d.ts +43 -0
  73. package/dist/prop.js +174 -0
  74. package/dist/render.d.ts +3 -0
  75. package/dist/render.js +7 -0
  76. package/dist/renderable.d.ts +5 -0
  77. package/dist/renderable.js +1 -0
  78. package/dist/types/clean.d.ts +2 -0
  79. package/dist/types/clean.js +1 -0
  80. package/dist/types/idom-context.d.ts +27 -0
  81. package/dist/types/idom-context.js +3 -0
  82. package/dist/types/renderable.d.ts +5 -0
  83. package/dist/types/renderable.js +1 -0
  84. package/package.json +5 -1
  85. package/.eslintignore +0 -10
  86. package/.eslintrc.cjs +0 -28
  87. package/coverage/clover.xml +0 -39
  88. package/coverage/coverage-final.json +0 -2
  89. package/coverage/lcov-report/OneOf.ts.html +0 -256
  90. package/coverage/lcov-report/base.css +0 -224
  91. package/coverage/lcov-report/block-navigation.js +0 -87
  92. package/coverage/lcov-report/dom-context.ts.html +0 -928
  93. package/coverage/lcov-report/favicon.png +0 -0
  94. package/coverage/lcov-report/index.html +0 -116
  95. package/coverage/lcov-report/prettify.css +0 -1
  96. package/coverage/lcov-report/prettify.js +0 -2
  97. package/coverage/lcov-report/prop.ts.html +0 -691
  98. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  99. package/coverage/lcov-report/sorter.js +0 -196
  100. package/coverage/lcov-report/src/components/Attribute.ts.html +0 -154
  101. package/coverage/lcov-report/src/components/BooleanAttribute.ts.html +0 -154
  102. package/coverage/lcov-report/src/components/ClassName.ts.html +0 -151
  103. package/coverage/lcov-report/src/components/El.ts.html +0 -166
  104. package/coverage/lcov-report/src/components/FadeIn.ts.html +0 -262
  105. package/coverage/lcov-report/src/components/FadeOut.ts.html +0 -226
  106. package/coverage/lcov-report/src/components/For.ts.html +0 -151
  107. package/coverage/lcov-report/src/components/Fragment.ts.html +0 -142
  108. package/coverage/lcov-report/src/components/HiddenWhenEmpty.ts.html +0 -133
  109. package/coverage/lcov-report/src/components/If.ts.html +0 -217
  110. package/coverage/lcov-report/src/components/InnerHTML.ts.html +0 -178
  111. package/coverage/lcov-report/src/components/Lifecycle.ts.html +0 -157
  112. package/coverage/lcov-report/src/components/Match.ts.html +0 -286
  113. package/coverage/lcov-report/src/components/NotEmpty.tsx.html +0 -184
  114. package/coverage/lcov-report/src/components/On.ts.html +0 -151
  115. package/coverage/lcov-report/src/components/OnRemove.ts.html +0 -145
  116. package/coverage/lcov-report/src/components/OneOf.ts.html +0 -256
  117. package/coverage/lcov-report/src/components/Portal.ts.html +0 -175
  118. package/coverage/lcov-report/src/components/Property.ts.html +0 -154
  119. package/coverage/lcov-report/src/components/Provider.ts.html +0 -244
  120. package/coverage/lcov-report/src/components/Repeat.ts.html +0 -223
  121. package/coverage/lcov-report/src/components/Show.tsx.html +0 -190
  122. package/coverage/lcov-report/src/components/Text.ts.html +0 -229
  123. package/coverage/lcov-report/src/components/TextContent.ts.html +0 -178
  124. package/coverage/lcov-report/src/components/Tween.tsx.html +0 -943
  125. package/coverage/lcov-report/src/components/animatable.ts.html +0 -619
  126. package/coverage/lcov-report/src/components/index.html +0 -476
  127. package/coverage/lcov-report/src/dom-context.ts.html +0 -928
  128. package/coverage/lcov-report/src/helpers/handle-anchor-click.ts.html +0 -277
  129. package/coverage/lcov-report/src/helpers/handle-text-input.ts.html +0 -100
  130. package/coverage/lcov-report/src/helpers/index.html +0 -146
  131. package/coverage/lcov-report/src/helpers/is-empty-element.ts.html +0 -112
  132. package/coverage/lcov-report/src/index.html +0 -176
  133. package/coverage/lcov-report/src/index.ts.html +0 -412
  134. package/coverage/lcov-report/src/jsx-runtime.ts.html +0 -601
  135. package/coverage/lcov-report/src/prop.ts.html +0 -691
  136. package/coverage/lcov-report/src/render.ts.html +0 -112
  137. package/coverage/lcov-report/src/types/idom-context.ts.html +0 -184
  138. package/coverage/lcov-report/src/types/index.html +0 -116
  139. package/coverage/lcov-report/test/common.ts.html +0 -112
  140. package/coverage/lcov-report/test/index.html +0 -116
  141. package/coverage/lcov.info +0 -57
  142. package/jest.config.js +0 -5
  143. package/src/clean.ts +0 -2
  144. package/src/components/Attribute.ts +0 -23
  145. package/src/components/BooleanAttribute.ts +0 -23
  146. package/src/components/ClassName.ts +0 -22
  147. package/src/components/El.ts +0 -27
  148. package/src/components/FadeIn.ts +0 -59
  149. package/src/components/FadeOut.ts +0 -47
  150. package/src/components/For.ts +0 -22
  151. package/src/components/Fragment.ts +0 -19
  152. package/src/components/HiddenWhenEmpty.ts +0 -16
  153. package/src/components/If.ts +0 -44
  154. package/src/components/InnerHTML.ts +0 -31
  155. package/src/components/Lifecycle.ts +0 -24
  156. package/src/components/Match.ts +0 -67
  157. package/src/components/NotEmpty.tsx +0 -33
  158. package/src/components/On.ts +0 -22
  159. package/src/components/OnRemove.ts +0 -20
  160. package/src/components/OneOf.ts +0 -57
  161. package/src/components/Portal.ts +0 -30
  162. package/src/components/Property.ts +0 -23
  163. package/src/components/Provider.ts +0 -53
  164. package/src/components/Repeat.ts +0 -46
  165. package/src/components/Show.tsx +0 -35
  166. package/src/components/Text.ts +0 -48
  167. package/src/components/TextContent.ts +0 -31
  168. package/src/components/animatable.ts +0 -178
  169. package/src/dom-context.ts +0 -281
  170. package/src/helpers/handle-anchor-click.ts +0 -64
  171. package/src/helpers/handle-text-input.ts +0 -5
  172. package/src/helpers/is-empty-element.ts +0 -9
  173. package/src/index.ts +0 -109
  174. package/src/jsx-dev-runtime.ts +0 -8
  175. package/src/jsx-runtime.ts +0 -172
  176. package/src/jsx.ts +0 -1046
  177. package/src/prop.ts +0 -202
  178. package/src/render.ts +0 -9
  179. package/src/renderable.ts +0 -6
  180. package/test/common.ts +0 -9
  181. package/test/component.spec.tsx +0 -27
  182. package/test/domcontext.spec.ts +0 -36
  183. package/test/fadein.spec.tsx +0 -36
  184. package/test/fadeout.spec.tsx +0 -41
  185. package/test/if.spec.tsx +0 -30
  186. package/test/innerhtml.spec.tsx +0 -45
  187. package/test/prop.spec.ts +0 -10
  188. package/test/render.spec.tsx +0 -19
  189. package/test/textcontent.spec.tsx +0 -45
  190. package/test/when.spec.tsx +0 -30
  191. package/tsconfig.json +0 -21
@@ -1,57 +0,0 @@
1
- TN:
2
- SF:src/components/OneOf.ts
3
- FN:10,(anonymous_0)
4
- FN:16,(anonymous_1)
5
- FN:24,(anonymous_2)
6
- FN:26,(anonymous_3)
7
- FN:38,(anonymous_4)
8
- FN:39,(anonymous_5)
9
- FN:42,(anonymous_6)
10
- FN:55,OneOf
11
- FNF:8
12
- FNH:4
13
- FNDA:7,(anonymous_0)
14
- FNDA:7,(anonymous_1)
15
- FNDA:7,(anonymous_2)
16
- FNDA:7,(anonymous_3)
17
- FNDA:0,(anonymous_4)
18
- FNDA:0,(anonymous_5)
19
- FNDA:0,(anonymous_6)
20
- FNDA:0,OneOf
21
- DA:1,8
22
- DA:6,8
23
- DA:9,8
24
- DA:11,7
25
- DA:12,7
26
- DA:16,7
27
- DA:17,7
28
- DA:18,7
29
- DA:19,7
30
- DA:20,7
31
- DA:21,7
32
- DA:22,7
33
- DA:23,7
34
- DA:24,7
35
- DA:25,7
36
- DA:26,7
37
- DA:27,7
38
- DA:28,7
39
- DA:29,7
40
- DA:30,7
41
- DA:31,7
42
- DA:32,7
43
- DA:35,0
44
- DA:38,7
45
- DA:39,0
46
- DA:40,0
47
- DA:41,0
48
- DA:42,0
49
- DA:55,8
50
- DA:56,0
51
- LF:30
52
- LH:24
53
- BRDA:25,0,0,7
54
- BRDA:25,0,1,0
55
- BRF:2
56
- BRH:1
57
- end_of_record
package/jest.config.js DELETED
@@ -1,5 +0,0 @@
1
- /** @type {import('ts-jest').JestConfigWithTsJest} */
2
- module.exports = {
3
- preset: 'ts-jest',
4
- testEnvironment: '@happy-dom/jest-environment',
5
- };
package/src/clean.ts DELETED
@@ -1,2 +0,0 @@
1
- export type Clear = (removeTree: boolean) => void
2
- export type Clean = () => void
@@ -1,23 +0,0 @@
1
- import { type DOMContext } from '../dom-context'
2
- import { type Signal } from '../prop'
3
- import { type Clear } from '../clean'
4
- import { type Renderable } from '../renderable'
5
- import { subscribeToSignal } from './Text'
6
-
7
- export class AttributeImpl implements Renderable {
8
- constructor(private readonly name: string, private readonly value: Signal<string>) { }
9
-
10
- readonly appendTo = (ctx: DOMContext): Clear => {
11
- const [set, clear] = ctx.createAttribute(this.name, this.value.get())
12
- return subscribeToSignal(this.value, set, clear)
13
- }
14
- }
15
-
16
- export interface AttributeProps {
17
- name: string
18
- value: Signal<string>
19
- }
20
-
21
- export function Attribute({ name, value }: AttributeProps): Renderable {
22
- return new AttributeImpl(name, value)
23
- }
@@ -1,23 +0,0 @@
1
- import { type DOMContext } from '../dom-context'
2
- import { type Signal } from '../prop'
3
- import { type Clear } from '../clean'
4
- import { type Renderable } from '../renderable'
5
- import { subscribeToSignal } from './Text'
6
-
7
- export class BooleanAttributeImpl implements Renderable {
8
- constructor(private readonly name: string, private readonly value: Signal<boolean>) { }
9
-
10
- readonly appendTo = (ctx: DOMContext): Clear => {
11
- const [set, clear] = ctx.createBooleanAttribute(this.name, this.value.get())
12
- return subscribeToSignal(this.value, set, clear)
13
- }
14
- }
15
-
16
- export interface BooleanAttributeProps {
17
- name: string
18
- value: Signal<boolean>
19
- }
20
-
21
- export function BooleanAttribute({ name, value }: BooleanAttributeProps): Renderable {
22
- return new BooleanAttributeImpl(name, value)
23
- }
@@ -1,22 +0,0 @@
1
- import { type Signal } from '../prop'
2
- import { type Renderable } from '../renderable'
3
- import { type Clear } from '../clean'
4
- import { subscribeToSignal } from './Text'
5
- import { type DOMContext } from '../dom-context'
6
-
7
- export class ClassNameImpl implements Renderable {
8
- constructor(private readonly cls: Signal<string> | Signal<string | undefined>) { }
9
-
10
- readonly appendTo = (ctx: DOMContext): Clear => {
11
- const [set, clear] = ctx.createClass(this.cls.get() ?? '')
12
- return subscribeToSignal(this.cls.map(v => v ?? ''), set, clear)
13
- }
14
- }
15
-
16
- export interface ClassNameProps {
17
- value: Signal<string> | Signal<string | undefined>
18
- }
19
-
20
- export function ClassName({ value }: ClassNameProps): Renderable {
21
- return new ClassNameImpl(value)
22
- }
@@ -1,27 +0,0 @@
1
- import { type DOMContext } from '../dom-context'
2
- import { type Clear } from '../clean'
3
- import { type Renderable } from '../renderable'
4
- import { type JSX } from '../jsx'
5
- import { makeRenderables } from '../jsx-runtime'
6
-
7
- export class ElImpl implements Renderable {
8
- constructor(private readonly tagName: string, private readonly children: Renderable[]) { }
9
- readonly appendTo = (ctx: DOMContext): Clear => {
10
- const newCtx = ctx.makeElement(this.tagName)
11
- const clears = this.children.map(child => child.appendTo(newCtx))
12
- return (removeTree: boolean) => {
13
- newCtx.requestClear(removeTree, () => {
14
- clears.forEach(clear => { clear(false) })
15
- })
16
- }
17
- }
18
- }
19
-
20
- export interface ElProps {
21
- tagName: string
22
- children?: JSX.DOMNode
23
- }
24
-
25
- export function El({ tagName, children }: ElProps): Renderable {
26
- return new ElImpl(tagName, makeRenderables(children))
27
- }
@@ -1,59 +0,0 @@
1
- import { Clear } from "../clean"
2
- import { DOMContext } from "../dom-context"
3
- import { Renderable } from "../renderable"
4
- import { getComputedAnimatable, Animatable, applyInterpolatedAnimatable, applyAnimatable } from "./animatable"
5
-
6
- export class FadeInImpl implements Renderable {
7
- constructor(
8
- private readonly end: Animatable,
9
- private readonly start: Animatable | undefined,
10
- private readonly duration: number,
11
- private readonly delay: number
12
- ) { }
13
-
14
- appendTo(ctx: DOMContext): Clear {
15
- const el = ctx.getElement()
16
- const start = (() => {
17
- if (this.start != null) {
18
- applyAnimatable(el, this.start)
19
- return this.start
20
- } else {
21
- return getComputedAnimatable(el, this.end)
22
- }
23
- })()
24
- const startTime = Date.now() + this.delay
25
- const { duration, end } = this
26
- let nextFrameId: null | number = null
27
- function frame() {
28
- const now = Date.now()
29
- if (now < startTime) {
30
- nextFrameId = requestAnimationFrame(frame)
31
- return
32
- }
33
-
34
- const progress = Math.min((now - startTime) / duration, 1)
35
- applyInterpolatedAnimatable(el, start, end, progress)
36
- if (progress < 1) {
37
- nextFrameId = requestAnimationFrame(frame)
38
- } else {
39
- nextFrameId = null
40
- }
41
- }
42
- frame()
43
-
44
- return (_: boolean) => {
45
- if (nextFrameId != null) cancelAnimationFrame(nextFrameId)
46
- }
47
- }
48
- }
49
-
50
- export interface FadeInProps extends Animatable {
51
- start?: Animatable,
52
- duration?: number,
53
- delay?: number
54
- }
55
-
56
- export function FadeIn(props: FadeInProps): Renderable {
57
- const { start, duration, delay, ...end } = props
58
- return new FadeInImpl(end, start, duration ?? 200, delay ?? 0)
59
- }
@@ -1,47 +0,0 @@
1
- import { Clear } from "../clean"
2
- import { DOMContext } from "../dom-context"
3
- import { Renderable } from "../renderable"
4
- import { getComputedAnimatable, Animatable, applyInterpolatedAnimatable } from "./animatable"
5
-
6
- export class FadeOutImpl implements Renderable {
7
- constructor(
8
- private readonly end: Animatable,
9
- private readonly duration: number,
10
- private readonly delay: number
11
- ) { }
12
-
13
- appendTo(ctx: DOMContext): Clear {
14
- const el = ctx.getElement()
15
- const { duration, end } = this
16
-
17
- return ctx.delayClear((removeTree, clear) => {
18
- const start = getComputedAnimatable(el, this.end)
19
- const startTime = Date.now() + this.delay
20
- function frame() {
21
- const now = Date.now()
22
- if (now < startTime) {
23
- requestAnimationFrame(frame)
24
- return
25
- }
26
- const progress = Math.min((now - startTime) / duration, 1)
27
- applyInterpolatedAnimatable(el, start, end, progress)
28
- if (progress < 1) {
29
- requestAnimationFrame(frame)
30
- } else {
31
- clear()
32
- }
33
- }
34
- requestAnimationFrame(frame)
35
- })
36
- }
37
- }
38
-
39
- export interface FadeOutProps extends Animatable {
40
- duration?: number,
41
- delay?: number
42
- }
43
-
44
- export function FadeOut(props: FadeOutProps): Renderable {
45
- const { duration, delay, ...end } = props
46
- return new FadeOutImpl(end, duration ?? 200, delay ?? 0)
47
- }
@@ -1,22 +0,0 @@
1
- import { type Signal } from '../prop'
2
- import { RepeatImpl } from './Repeat'
3
- import { type JSX, makeRenderable } from '../jsx-runtime'
4
- import { FragmentImpl } from './Fragment'
5
- import { OnRemoveImpl } from './OnRemove'
6
-
7
- export interface ForProps<T> {
8
- of: Signal<T[]>
9
- children?: (value: Signal<T>, index: number) => JSX.DOMNode
10
- }
11
-
12
- // <For of={values}>{(value) => <span>{value}</span>}</For>
13
- export function For<T>({ of, children: render }: ForProps<T>): JSX.DOMNode {
14
- const times = of.map(v => v.length)
15
- return new RepeatImpl(times, (index: number) => {
16
- const value = of.at(index)
17
- return new FragmentImpl([
18
- makeRenderable(render?.(value, index)),
19
- new OnRemoveImpl(value.clean)
20
- ])
21
- })
22
- }
@@ -1,19 +0,0 @@
1
- import { type Renderable } from '../renderable'
2
- import { type Clear } from '../clean'
3
- import { type DOMContext } from '../dom-context'
4
- import { type JSX } from '../jsx'
5
- import { makeRenderables } from '../jsx-runtime'
6
-
7
- export class FragmentImpl implements Renderable {
8
- constructor(private readonly children: Renderable[]) { }
9
- readonly appendTo = (ctx: DOMContext): Clear => {
10
- const clears = this.children.map(child => child.appendTo(ctx))
11
- return (removeTree: boolean) => {
12
- clears.forEach(clear => { clear(removeTree) })
13
- }
14
- }
15
- }
16
-
17
- export function Fragment({ children }: { children: JSX.DOMNode }): Renderable {
18
- return new FragmentImpl(makeRenderables(children))
19
- }
@@ -1,16 +0,0 @@
1
- import { type Renderable } from '../renderable'
2
- import { type DOMContext } from '../dom-context'
3
- import { type Clear } from '../clean'
4
-
5
- export class HiddenWhenEmptyImpl implements Renderable {
6
- appendTo(ctx: DOMContext): Clear {
7
- ctx.setStyle(':empty', 'display: none')
8
- return (removeTree) => {
9
- if (removeTree) ctx.setStyle(':empty', null)
10
- }
11
- }
12
- }
13
-
14
- export function HiddenWhenEmpty(): HiddenWhenEmptyImpl {
15
- return new HiddenWhenEmptyImpl()
16
- }
@@ -1,44 +0,0 @@
1
- import { type JSX } from '../jsx'
2
- import { type Signal } from '../prop'
3
- import { OneOfImpl } from './OneOf'
4
-
5
- export interface IfProps {
6
- is: Signal<boolean>
7
- then?: JSX.DOMNode
8
- otherwise?: JSX.DOMNode
9
- }
10
-
11
- export function If({ is, then, otherwise }: IfProps): JSX.DOMNode {
12
- return new OneOfImpl(
13
- is.map(v => v ? [1, true] as [1, true] : [2, false] as [2, false]),
14
- {
15
- 1: () => then,
16
- 2: () => otherwise
17
- }
18
- )
19
- }
20
-
21
- export interface WhenProps {
22
- is: Signal<boolean>
23
- children?: JSX.DOMNode
24
- }
25
-
26
- export function When({ is, children }: WhenProps): JSX.DOMNode {
27
- return new OneOfImpl(
28
- is.map(v => v ? [1, true] as [1, true] : [2, false] as [2, false]),
29
- {
30
- 1: () => children,
31
- 2: () => null
32
- }
33
- )
34
- }
35
-
36
- export function Unless({ is, children }: WhenProps): JSX.DOMNode {
37
- return new OneOfImpl(
38
- is.map(v => v ? [1, true] as [1, true] : [2, false] as [2, false]),
39
- {
40
- 1: () => null,
41
- 2: () => children
42
- }
43
- )
44
- }
@@ -1,31 +0,0 @@
1
- import { type Signal } from '../prop'
2
- import { type Clear } from '../clean'
3
- import { type DOMContext } from '../dom-context'
4
- import { type Renderable } from '../renderable'
5
-
6
- export class InnerHTMLImpl implements Renderable {
7
- constructor(private readonly html: Signal<string> | Signal<string | undefined>) { }
8
-
9
- readonly appendTo = (ctx: DOMContext): Clear => {
10
- const el = ctx.getElement()
11
- const previous = el.innerHTML
12
- el.innerHTML = this.html.get() ?? ''
13
- const cancel = this.html.subscribe(value => {
14
- el.innerHTML = value ?? ''
15
- })
16
- return (removeTree: boolean) => {
17
- cancel()
18
- if (removeTree) {
19
- el.innerHTML = previous
20
- }
21
- }
22
- }
23
- }
24
-
25
- export interface InnerHTMLProps {
26
- html: Signal<string> | Signal<string | undefined>
27
- }
28
-
29
- export function InnerHTML({ html }: InnerHTMLProps): InnerHTMLImpl {
30
- return new InnerHTMLImpl(html)
31
- }
@@ -1,24 +0,0 @@
1
- import { type Clear } from '../clean'
2
- import { type DOMContext } from '../dom-context'
3
- import { type Renderable } from '../renderable'
4
-
5
- export class LifecycleImpl implements Renderable {
6
- constructor(private readonly onMount: (el: HTMLElement) => void, private readonly onUnmount: (el: HTMLElement) => void) { }
7
- readonly appendTo = (ctx: DOMContext): Clear => {
8
- this.onMount(ctx.getElement())
9
-
10
- return () => {
11
- this.onUnmount(ctx.getElement())
12
- }
13
- }
14
- }
15
-
16
- export interface LifecycleProps {
17
- onMount?: (el: HTMLElement) => void
18
- onUnmount?: (el: HTMLElement) => void
19
- }
20
-
21
- export function Lifecycle({ onMount, onUnmount }: LifecycleProps): Renderable {
22
- // eslint-disable-next-line @typescript-eslint/no-empty-function
23
- return new LifecycleImpl(onMount ?? (() => { }), onUnmount ?? (() => { }))
24
- }
@@ -1,67 +0,0 @@
1
- import { type Signal } from '../prop'
2
- import { type DOMContext } from '../dom-context'
3
- import { type AnyKey } from './OneOf'
4
- import { type JSX, makeRenderable } from '../jsx-runtime'
5
- import { type Clear } from '../clean'
6
-
7
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
- export class MatchImpl<T extends { [_ in K]: any }, K extends keyof T> {
9
- constructor(
10
- private readonly on: Signal<T>,
11
- private readonly using: K,
12
- private readonly matches: {
13
- [KIND in T[K]]: (
14
- _: Signal<T & { [KK in K]: KIND extends T[KK] ? KIND : never }>
15
- ) => JSX.DOMNode
16
- }
17
- ) { }
18
-
19
- readonly appendTo = (ctx: DOMContext): Clear => {
20
- let newCtx = ctx.makeReference()
21
- const value = this.on.get()
22
- let key = value[this.using]
23
- let derived = this.on.map(v => v)
24
- let renderable = makeRenderable(this.matches[key](derived))
25
- let clear = renderable.appendTo(newCtx)
26
- const cancel = this.on.subscribe(newValue => {
27
- const newKey = newValue[this.using]
28
- if (newKey === key) return
29
- newCtx.requestClear(true, () => {
30
- clear(true)
31
- derived.clean()
32
- key = newKey
33
- derived = this.on.map(v => v)
34
- newCtx = newCtx.makeReference()
35
- renderable = makeRenderable(this.matches[key](derived))
36
- clear = renderable.appendTo(newCtx)
37
- })
38
- })
39
-
40
- return (removeTree: boolean) => {
41
- newCtx.requestClear(removeTree, () => {
42
- cancel()
43
- derived.clean()
44
- clear(removeTree)
45
- })
46
- }
47
- }
48
- }
49
-
50
- export type MatchProps<T extends { [_ in K]: AnyKey }, K extends keyof T> = {
51
- on: Signal<T>
52
- using: K
53
- } & {
54
- matches: {
55
- [KIND in T[K]]: (
56
- _: Signal<T & { [KK in K]: KIND extends T[KK] ? KIND : never }>
57
- ) => JSX.DOMNode
58
- }
59
- }
60
-
61
- export function Match<T extends { [_ in K]: AnyKey }, K extends keyof T>({
62
- on,
63
- using,
64
- matches
65
- }: MatchProps<T, K>): JSX.DOMNode {
66
- return new MatchImpl(on, using, matches)
67
- }
@@ -1,33 +0,0 @@
1
- /** @jsxImportSource .. */
2
- import { type Signal } from '../prop'
3
- import { If } from './If'
4
- import { type AnyKey } from './OneOf'
5
- import { type JSX } from '../jsx-runtime'
6
-
7
- export interface NotEmptyProps<T> {
8
- on: Signal<T>
9
- whenEmpty?: JSX.DOMNode
10
- display: JSX.DOMNode
11
- }
12
-
13
- function isEmpty(obj: Record<AnyKey, unknown>): boolean {
14
- return Object.keys(obj).length === 0
15
- }
16
-
17
- // <NotEmpty on={maybevalue} whenEmpty={<span>nothing to show</span>}}>{value => value.toText()}</NotEmpty>
18
- export function NotEmpty<T extends unknown[] | Record<AnyKey, unknown>>({
19
- on,
20
- display,
21
- whenEmpty
22
- }: NotEmptyProps<T>): JSX.DOMNode {
23
- return (
24
- <If
25
- is={on.map((v: T) =>
26
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
- Array.isArray(v) ? v.length > 0 : v != null && !isEmpty(v as any)
28
- )}
29
- then={display}
30
- otherwise={whenEmpty}
31
- />
32
- )
33
- }
@@ -1,22 +0,0 @@
1
- import { type Renderable } from '../renderable'
2
- import { type Clear } from '../clean'
3
- import { type DOMContext } from '../dom-context'
4
-
5
- export type OnFn<T> = (value: T) => void
6
-
7
- export class OnImpl<T> implements Renderable {
8
- constructor(private readonly name: string, private readonly handler: OnFn<T>) { }
9
-
10
- readonly appendTo = (ctx: DOMContext): Clear => {
11
- return ctx.createHandler(this.name, this.handler)
12
- }
13
- }
14
-
15
- export interface OnProps<T> {
16
- name: string
17
- handler: OnFn<T>
18
- }
19
-
20
- export function On<T>({ name, handler }: OnProps<T>): Renderable {
21
- return new OnImpl(name, handler)
22
- }
@@ -1,20 +0,0 @@
1
- import { type Clear } from '../clean'
2
- import { type Renderable } from '../renderable'
3
-
4
- export class OnRemoveImpl implements Renderable {
5
- constructor(private readonly clear: Clear) { }
6
-
7
- readonly appendTo = (): Clear => {
8
- return (removeTree: boolean) => {
9
- this.clear(removeTree)
10
- }
11
- }
12
- }
13
-
14
- export interface OnRemoveProps {
15
- clear: Clear
16
- }
17
-
18
- export function OnRemove(props: OnRemoveProps): OnRemoveImpl {
19
- return new OnRemoveImpl(props.clear)
20
- }
@@ -1,57 +0,0 @@
1
- import { Prop, type Signal } from '../prop'
2
- import { type Clear } from '../clean'
3
- import { type DOMContext } from '../dom-context'
4
- import { type Renderable } from '../renderable'
5
- import { type JSX } from '../jsx'
6
- import { makeRenderable } from '../jsx-runtime'
7
-
8
- export type AnyKey = string | number | symbol
9
- export class OneOfImpl<T extends [AnyKey, unknown]> implements Renderable {
10
- constructor (
11
- private readonly match: Signal<T>,
12
- private readonly cases: {
13
- [KK in T[0]]: (value: Signal<T[1]>) => JSX.DOMNode
14
- }) { }
15
-
16
- readonly appendTo = (ctx: DOMContext): Clear => {
17
- const pair: [T[0], T[1]] = this.match.get()
18
- let key = pair[0]
19
- const value = pair[1]
20
- const stableCtx = ctx.makeReference()
21
- let prop = new Prop(value)
22
- let newCtx = stableCtx.makeReference()
23
- let clear = makeRenderable(this.cases[key](prop)).appendTo(newCtx)
24
- const cancel = this.match.subscribe(([newKey, newValue]) => {
25
- if (newKey !== key) {
26
- newCtx.requestClear(true, () => {
27
- newCtx = stableCtx.makeReference()
28
- key = newKey
29
- prop.clean()
30
- prop = new Prop(newValue)
31
- clear(true)
32
- clear = makeRenderable(this.cases[key](prop)).appendTo(newCtx)
33
- })
34
- } else {
35
- prop.set(newValue)
36
- }
37
- })
38
- return (removeTree: boolean) => {
39
- newCtx.requestClear(removeTree, () => {
40
- cancel()
41
- prop.clean()
42
- stableCtx.requestClear(removeTree, () => { })
43
- })
44
- }
45
- }
46
- }
47
-
48
- export type OneOfProps<T extends [AnyKey, unknown]> = {
49
- match: Signal<T>
50
- } & {
51
- [KK in T[0]]: (value: Signal<T[1]>) => JSX.DOMNode
52
- }
53
-
54
- // <OneOf match={counter.map(v => v % 2 == 0 ? [1, "odd"] : [2, "even"])} 1={t => <b>{t}</b>} 2={t => <i>{t}</i>} /
55
- export function OneOf<T extends [AnyKey, unknown]> (props: OneOfProps<T>): JSX.DOMNode {
56
- return new OneOfImpl(props.match, props)
57
- }
@@ -1,30 +0,0 @@
1
- import { render } from '../render'
2
- import { type Clear } from '../clean'
3
- import { type DOMContext } from '../dom-context'
4
- import { type Renderable } from '../renderable'
5
- import { type JSX } from '../jsx'
6
- import { makeRenderable } from '../jsx-runtime'
7
-
8
- export class PortalImpl implements Renderable {
9
- constructor(
10
- private readonly selector: string,
11
- private readonly children: JSX.DOMNode
12
- ) { }
13
-
14
- appendTo(ctx: DOMContext): Clear {
15
- const element = ctx.getDocument().querySelector(this.selector)
16
- if (element === null) {
17
- throw new Error(`Cannot find element by selector: ${this.selector}`)
18
- }
19
- return render(makeRenderable(this.children), element as HTMLElement)
20
- }
21
- }
22
-
23
- export interface PortalProps {
24
- selector: string
25
- children?: JSX.DOMNode
26
- }
27
-
28
- export function Portal(props: PortalProps): JSX.DOMNode {
29
- return new PortalImpl(props.selector, props.children)
30
- }