@tempots/dom 5.0.1 → 5.1.0

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 (89) hide show
  1. package/README.md +1 -0
  2. package/components/For.d.ts +9 -0
  3. package/{dist/components → components}/For.js +2 -2
  4. package/{dist/components → components}/OneOf.js +1 -1
  5. package/components/Repeat.d.ts +25 -0
  6. package/components/Repeat.js +103 -0
  7. package/package.json +5 -7
  8. package/{dist/prop.d.ts → prop.d.ts} +2 -0
  9. package/{dist/prop.js → prop.js} +41 -0
  10. package/dist/components/For.d.ts +0 -7
  11. package/dist/components/Repeat.d.ts +0 -15
  12. package/dist/components/Repeat.js +0 -33
  13. /package/{dist/clean.d.ts → clean.d.ts} +0 -0
  14. /package/{dist/clean.js → clean.js} +0 -0
  15. /package/{dist/components → components}/Attribute.d.ts +0 -0
  16. /package/{dist/components → components}/Attribute.js +0 -0
  17. /package/{dist/components → components}/BooleanAttribute.d.ts +0 -0
  18. /package/{dist/components → components}/BooleanAttribute.js +0 -0
  19. /package/{dist/components → components}/ClassName.d.ts +0 -0
  20. /package/{dist/components → components}/ClassName.js +0 -0
  21. /package/{dist/components → components}/El.d.ts +0 -0
  22. /package/{dist/components → components}/El.js +0 -0
  23. /package/{dist/components → components}/FadeIn.d.ts +0 -0
  24. /package/{dist/components → components}/FadeIn.js +0 -0
  25. /package/{dist/components → components}/FadeOut.d.ts +0 -0
  26. /package/{dist/components → components}/FadeOut.js +0 -0
  27. /package/{dist/components → components}/Fragment.d.ts +0 -0
  28. /package/{dist/components → components}/Fragment.js +0 -0
  29. /package/{dist/components → components}/HiddenWhenEmpty.d.ts +0 -0
  30. /package/{dist/components → components}/HiddenWhenEmpty.js +0 -0
  31. /package/{dist/components → components}/If.d.ts +0 -0
  32. /package/{dist/components → components}/If.js +0 -0
  33. /package/{dist/components → components}/InnerHTML.d.ts +0 -0
  34. /package/{dist/components → components}/InnerHTML.js +0 -0
  35. /package/{dist/components → components}/Lifecycle.d.ts +0 -0
  36. /package/{dist/components → components}/Lifecycle.js +0 -0
  37. /package/{dist/components → components}/Match.d.ts +0 -0
  38. /package/{dist/components → components}/Match.js +0 -0
  39. /package/{dist/components → components}/NotEmpty.d.ts +0 -0
  40. /package/{dist/components → components}/NotEmpty.js +0 -0
  41. /package/{dist/components → components}/On.d.ts +0 -0
  42. /package/{dist/components → components}/On.js +0 -0
  43. /package/{dist/components → components}/OnRemove.d.ts +0 -0
  44. /package/{dist/components → components}/OnRemove.js +0 -0
  45. /package/{dist/components → components}/OneOf.d.ts +0 -0
  46. /package/{dist/components → components}/Portal.d.ts +0 -0
  47. /package/{dist/components → components}/Portal.js +0 -0
  48. /package/{dist/components → components}/Property.d.ts +0 -0
  49. /package/{dist/components → components}/Property.js +0 -0
  50. /package/{dist/components → components}/Provider.d.ts +0 -0
  51. /package/{dist/components → components}/Provider.js +0 -0
  52. /package/{dist/components → components}/Shadow.d.ts +0 -0
  53. /package/{dist/components → components}/Shadow.js +0 -0
  54. /package/{dist/components → components}/Show.d.ts +0 -0
  55. /package/{dist/components → components}/Show.js +0 -0
  56. /package/{dist/components → components}/Text.d.ts +0 -0
  57. /package/{dist/components → components}/Text.js +0 -0
  58. /package/{dist/components → components}/TextContent.d.ts +0 -0
  59. /package/{dist/components → components}/TextContent.js +0 -0
  60. /package/{dist/components → components}/Tween.d.ts +0 -0
  61. /package/{dist/components → components}/Tween.js +0 -0
  62. /package/{dist/components → components}/animatable.d.ts +0 -0
  63. /package/{dist/components → components}/animatable.js +0 -0
  64. /package/{dist/dom-context.d.ts → dom-context.d.ts} +0 -0
  65. /package/{dist/dom-context.js → dom-context.js} +0 -0
  66. /package/{dist/helpers → helpers}/handle-anchor-click.d.ts +0 -0
  67. /package/{dist/helpers → helpers}/handle-anchor-click.js +0 -0
  68. /package/{dist/helpers → helpers}/handle-text-input.d.ts +0 -0
  69. /package/{dist/helpers → helpers}/handle-text-input.js +0 -0
  70. /package/{dist/helpers → helpers}/is-empty-element.d.ts +0 -0
  71. /package/{dist/helpers → helpers}/is-empty-element.js +0 -0
  72. /package/{dist/index.d.ts → index.d.ts} +0 -0
  73. /package/{dist/index.js → index.js} +0 -0
  74. /package/{dist/jsx-dev-runtime.d.ts → jsx-dev-runtime.d.ts} +0 -0
  75. /package/{dist/jsx-dev-runtime.js → jsx-dev-runtime.js} +0 -0
  76. /package/{dist/jsx-runtime.d.ts → jsx-runtime.d.ts} +0 -0
  77. /package/{dist/jsx-runtime.js → jsx-runtime.js} +0 -0
  78. /package/{dist/jsx.d.ts → jsx.d.ts} +0 -0
  79. /package/{dist/jsx.js → jsx.js} +0 -0
  80. /package/{dist/render.d.ts → render.d.ts} +0 -0
  81. /package/{dist/render.js → render.js} +0 -0
  82. /package/{dist/renderable.d.ts → renderable.d.ts} +0 -0
  83. /package/{dist/renderable.js → renderable.js} +0 -0
  84. /package/{dist/types → types}/clean.d.ts +0 -0
  85. /package/{dist/types → types}/clean.js +0 -0
  86. /package/{dist/types → types}/idom-context.d.ts +0 -0
  87. /package/{dist/types → types}/idom-context.js +0 -0
  88. /package/{dist/types → types}/renderable.d.ts +0 -0
  89. /package/{dist/types → types}/renderable.js +0 -0
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # @tempots/dom
@@ -0,0 +1,9 @@
1
+ import { type Signal } from '../prop';
2
+ import { SeparatorProps } from './Repeat';
3
+ import { type JSX } from '../jsx-runtime';
4
+ export interface ForProps<T> {
5
+ of: Signal<T[]>;
6
+ separator?: (value: Signal<SeparatorProps>) => JSX.DOMNode;
7
+ children?: (value: Signal<T>, index: number) => JSX.DOMNode;
8
+ }
9
+ export declare function For<T>({ of, children: render, separator }: ForProps<T>): JSX.DOMNode;
@@ -3,7 +3,7 @@ import { makeRenderable } from '../jsx-runtime';
3
3
  import { FragmentImpl } from './Fragment';
4
4
  import { OnRemoveImpl } from './OnRemove';
5
5
  // <For of={values}>{(value) => <span>{value}</span>}</For>
6
- export function For({ of, children: render }) {
6
+ export function For({ of, children: render, separator }) {
7
7
  const times = of.map(v => v.length);
8
8
  return new RepeatImpl(times, (index) => {
9
9
  const value = of.at(index);
@@ -11,5 +11,5 @@ export function For({ of, children: render }) {
11
11
  makeRenderable(render?.(value, index)),
12
12
  new OnRemoveImpl(value.clean)
13
13
  ]);
14
- });
14
+ }, separator);
15
15
  }
@@ -11,8 +11,8 @@ export class OneOfImpl {
11
11
  const pair = this.match.get();
12
12
  let key = pair[0];
13
13
  const value = pair[1];
14
+ const stableCtx = ctx.makeReference();
14
15
  let prop = new Prop(value);
15
- let stableCtx = ctx.makeReference();
16
16
  let newCtx = stableCtx.makeReference();
17
17
  let clear = makeRenderable(this.cases[key](prop)).appendTo(newCtx);
18
18
  const cancel = this.match.subscribe(([newKey, newValue]) => {
@@ -0,0 +1,25 @@
1
+ import { Signal } from '../prop';
2
+ import { type Clear } from '../clean';
3
+ import { type DOMContext } from '../dom-context';
4
+ import { type Renderable } from '../renderable';
5
+ import { JSX } from '../jsx';
6
+ export interface SeparatorProps {
7
+ first: boolean;
8
+ last: boolean;
9
+ index: number;
10
+ }
11
+ export declare class RepeatImpl implements Renderable {
12
+ private readonly times;
13
+ private readonly children;
14
+ private readonly separator?;
15
+ constructor(times: Signal<number>, children: (index: number) => JSX.DOMNode, separator?: ((sep: Signal<SeparatorProps>) => JSX.DOMNode) | undefined);
16
+ readonly appendTo: (ctx: DOMContext) => Clear;
17
+ readonly appendToWithoutSeparator: (ctx: DOMContext) => Clear;
18
+ readonly appendToWithSeparator: (ctx: DOMContext, separator: (sep: Signal<SeparatorProps>) => JSX.DOMNode) => Clear;
19
+ }
20
+ export interface RepeatProps {
21
+ times: Signal<number>;
22
+ children?: (index: number) => JSX.DOMNode;
23
+ separator?: (sep: Signal<SeparatorProps>) => JSX.DOMNode;
24
+ }
25
+ export declare function Repeat(props: RepeatProps): Renderable;
@@ -0,0 +1,103 @@
1
+ import { Prop } from '../prop';
2
+ import { Fragment } from './Fragment';
3
+ import { makeRenderable } from '../jsx-runtime';
4
+ export class RepeatImpl {
5
+ times;
6
+ children;
7
+ separator;
8
+ constructor(times, children, separator) {
9
+ this.times = times;
10
+ this.children = children;
11
+ this.separator = separator;
12
+ }
13
+ appendTo = (ctx) => {
14
+ if (!this.separator) {
15
+ return this.appendToWithoutSeparator(ctx);
16
+ }
17
+ else {
18
+ return this.appendToWithSeparator(ctx, this.separator);
19
+ }
20
+ };
21
+ appendToWithoutSeparator = (ctx) => {
22
+ const newCtx = ctx.makeReference();
23
+ const count = this.times.get();
24
+ const clears = new Array(count);
25
+ for (let i = 0; i < count; i++) {
26
+ clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
27
+ }
28
+ const cancel = this.times.subscribe((newCount) => {
29
+ while (newCount < clears.length) {
30
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31
+ clears.pop()(true);
32
+ }
33
+ for (let i = clears.length; i < newCount; i++) {
34
+ clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
35
+ }
36
+ });
37
+ return (removeTree) => {
38
+ newCtx.requestClear(removeTree, () => {
39
+ cancel();
40
+ clears.forEach(clear => { clear(removeTree); });
41
+ });
42
+ };
43
+ };
44
+ appendToWithSeparator = (ctx, separator) => {
45
+ const newCtx = ctx.makeReference();
46
+ const count = this.times.get();
47
+ const separatorProps = new Array(Math.max(0, count - 1));
48
+ const separatorClears = new Array(Math.max(0, count - 1));
49
+ const clears = new Array(count);
50
+ for (let i = 0; i < count; i++) {
51
+ clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
52
+ if (i < count - 1) {
53
+ separatorProps[i] = Prop.of({
54
+ first: i === 0,
55
+ last: i === count - 2,
56
+ index: i
57
+ });
58
+ separatorClears[i] = makeRenderable(separator(separatorProps[i])).appendTo(newCtx);
59
+ }
60
+ }
61
+ const cancel = this.times.subscribe((newCount) => {
62
+ while (newCount < clears.length) {
63
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
64
+ clears.pop()(true);
65
+ if (separatorClears.length > 0) {
66
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67
+ separatorClears.pop()(true);
68
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
69
+ separatorProps.pop().clean();
70
+ }
71
+ }
72
+ for (let i = 0; i < separatorProps.length; i++) {
73
+ separatorProps[i].set({
74
+ first: i === 0,
75
+ last: i === newCount - 2,
76
+ index: i
77
+ });
78
+ }
79
+ for (let i = clears.length; i < newCount; i++) {
80
+ clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
81
+ if (i < newCount - 1) {
82
+ separatorProps[i] = Prop.of({
83
+ first: i === 0,
84
+ last: i === newCount - 2,
85
+ index: i
86
+ });
87
+ separatorClears[i] = makeRenderable(separator(separatorProps[i])).appendTo(newCtx);
88
+ }
89
+ }
90
+ });
91
+ return (removeTree) => {
92
+ newCtx.requestClear(removeTree, () => {
93
+ cancel();
94
+ clears.forEach(clear => { clear(removeTree); });
95
+ separatorClears.forEach(clear => { clear(removeTree); });
96
+ separatorProps.forEach(signal => { signal.clean(); });
97
+ });
98
+ };
99
+ };
100
+ }
101
+ export function Repeat(props) {
102
+ return new RepeatImpl(props.times, props.children ?? (() => Fragment({ children: [] })), props.separator);
103
+ }
package/package.json CHANGED
@@ -1,19 +1,17 @@
1
1
  {
2
2
  "name": "@tempots/dom",
3
- "version": "5.0.1",
4
- "main": "dist/index.js",
5
- "types": "dist/index.d.ts",
3
+ "main": "index.js",
4
+ "types": "index.d.ts",
5
+ "version": "5.1.0",
6
6
  "scripts": {
7
7
  "watch": "tsc --watch",
8
8
  "build": "tsc",
9
9
  "test": "jest",
10
10
  "test:watch": "jest --watch",
11
11
  "coverage": "jest --coverage",
12
- "npm:publish": "yarn publish --access public"
12
+ "npm:prep": "yarn build && cp README.md package.json dist",
13
+ "npm:publish": "yarn npm:prep && (cd dist && yarn publish --access public)"
13
14
  },
14
- "files": [
15
- "dist"
16
- ],
17
15
  "dependencies": {},
18
16
  "devDependencies": {
19
17
  "@happy-dom/jest-environment": "^9.1.7",
@@ -29,6 +29,8 @@ export declare class Signal<T> {
29
29
  readonly feed: (prop: Prop<T>) => Prop<T>;
30
30
  readonly deriveProp: () => Prop<T>;
31
31
  readonly clean: () => void;
32
+ readonly count: () => Signal<number>;
33
+ readonly animate: (duration: number, interpolate: (start: T, end: T, delta: number) => T, initialValue?: T | null, easing?: (t: number) => number) => Signal<T>;
32
34
  }
33
35
  export declare class Prop<T> extends Signal<T> {
34
36
  static isProp<T = unknown>(x: unknown): x is Prop<T>;
@@ -137,6 +137,47 @@ export class Signal {
137
137
  clean = () => {
138
138
  this._listeners.length = 0;
139
139
  };
140
+ count = () => {
141
+ let count = 0;
142
+ return this.map(() => ++count);
143
+ };
144
+ animate = (duration, interpolate, initialValue = null, easing = t => t) => {
145
+ let startValue = initialValue ?? this.get();
146
+ let endValue = this.get();
147
+ const prop = new Prop(startValue);
148
+ let startTime = 0;
149
+ let endTime = 0;
150
+ let animationFrame = null;
151
+ const animate = (time) => {
152
+ if (this._listeners.length === 0) {
153
+ animationFrame = null;
154
+ return;
155
+ }
156
+ if (time < endTime) {
157
+ const delta = (time - startTime) / (endTime - startTime);
158
+ prop.set(interpolate(startValue, endValue, easing(delta)));
159
+ animationFrame = requestAnimationFrame(animate);
160
+ }
161
+ else {
162
+ prop.set(endValue);
163
+ animationFrame = null;
164
+ }
165
+ };
166
+ this.subscribe(value => {
167
+ if (animationFrame != null)
168
+ cancelAnimationFrame(animationFrame);
169
+ if (this._listeners.length === 0) {
170
+ animationFrame = null;
171
+ return;
172
+ }
173
+ startValue = prop.get();
174
+ endValue = value;
175
+ startTime = performance.now();
176
+ endTime = startTime + duration;
177
+ animationFrame = requestAnimationFrame(animate);
178
+ });
179
+ return prop;
180
+ };
140
181
  }
141
182
  export class Prop extends Signal {
142
183
  static isProp(x) {
@@ -1,7 +0,0 @@
1
- import { type Signal } from '../prop';
2
- import { type JSX } from '../jsx-runtime';
3
- export interface ForProps<T> {
4
- of: Signal<T[]>;
5
- children?: (value: Signal<T>, index: number) => JSX.DOMNode;
6
- }
7
- export declare function For<T>({ of, children: render }: ForProps<T>): JSX.DOMNode;
@@ -1,15 +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
- export declare class RepeatImpl implements Renderable {
6
- private readonly times;
7
- private readonly children;
8
- constructor(times: Signal<number>, children: (index: number) => Renderable);
9
- readonly appendTo: (ctx: DOMContext) => Clear;
10
- }
11
- export interface RepeatProps {
12
- times: Signal<number>;
13
- children?: (index: number) => Renderable;
14
- }
15
- export declare function Repeat(props: RepeatProps): Renderable;
@@ -1,33 +0,0 @@
1
- import { Fragment } from './Fragment';
2
- export class RepeatImpl {
3
- times;
4
- children;
5
- constructor(times, children) {
6
- this.times = times;
7
- this.children = children;
8
- }
9
- appendTo = (ctx) => {
10
- const newCtx = ctx.makeReference();
11
- const count = this.times.get();
12
- const clears = new Array(count);
13
- for (let i = 0; i < count; i++) {
14
- clears[i] = this.children(i).appendTo(newCtx);
15
- }
16
- const cancel = this.times.subscribe((newCount) => {
17
- while (newCount < clears.length) {
18
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
19
- clears.pop()(true);
20
- }
21
- for (let i = clears.length; i < newCount; i++) {
22
- clears[i] = this.children(i).appendTo(newCtx);
23
- }
24
- });
25
- return (removeTree) => {
26
- newCtx.requestClear(removeTree, () => {
27
- cancel();
28
- clears.forEach(clear => { clear(removeTree); });
29
- });
30
- };
31
- };
32
- }
33
- export function Repeat(props) { return new RepeatImpl(props.times, props.children ?? (() => Fragment({ children: [] }))); }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes