@tempots/dom 6.0.0 → 7.0.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.
@@ -1,7 +1,7 @@
1
- import { Clear } from "../clean";
2
- import { DOMContext } from "../dom-context";
3
- import { Renderable } from "../renderable";
4
- import { Animatable } from "./animatable";
1
+ import { type Clear } from '../clean';
2
+ import { type DOMContext } from '../dom-context';
3
+ import { type Renderable } from '../renderable';
4
+ import { type Animatable } from './animatable';
5
5
  export declare class FadeInImpl implements Renderable {
6
6
  private readonly end;
7
7
  private readonly start;
@@ -1,4 +1,4 @@
1
- import { getComputedAnimatable, applyInterpolatedAnimatable, applyAnimatable } from "./animatable";
1
+ import { getComputedAnimatable, applyInterpolatedAnimatable, applyAnimatable } from './animatable';
2
2
  export class FadeInImpl {
3
3
  end;
4
4
  start;
@@ -1,7 +1,7 @@
1
- import { Clear } from "../clean";
2
- import { DOMContext } from "../dom-context";
3
- import { Renderable } from "../renderable";
4
- import { Animatable } from "./animatable";
1
+ import { type Clear } from '../clean';
2
+ import { type DOMContext } from '../dom-context';
3
+ import { type Renderable } from '../renderable';
4
+ import { type Animatable } from './animatable';
5
5
  export declare class FadeOutImpl implements Renderable {
6
6
  private readonly end;
7
7
  private readonly duration;
@@ -1,4 +1,4 @@
1
- import { getComputedAnimatable, applyInterpolatedAnimatable } from "./animatable";
1
+ import { getComputedAnimatable, applyInterpolatedAnimatable } from './animatable';
2
2
  export class FadeOutImpl {
3
3
  end;
4
4
  duration;
@@ -1,9 +1,18 @@
1
1
  import { type Signal } from '../prop';
2
- import { SeparatorProps } from './Repeat';
2
+ import { type PositionProps } from './Repeat';
3
3
  import { type JSX } from '../jsx-runtime';
4
4
  export interface ForProps<T> {
5
5
  of: Signal<T[]>;
6
- separator?: (value: Signal<SeparatorProps>) => JSX.DOMNode;
7
- children?: (value: Signal<T>, index: number) => JSX.DOMNode;
6
+ separator?: (value: Signal<PositionProps>) => JSX.DOMNode;
7
+ children?: (value: Signal<T>, pos: Signal<PositionProps>) => JSX.DOMNode;
8
8
  }
9
9
  export declare function For<T>({ of, children: render, separator }: ForProps<T>): JSX.DOMNode;
10
+ export interface ForWithPositionProps<T> {
11
+ of: Signal<T[]>;
12
+ separator?: (value: Signal<PositionProps>) => JSX.DOMNode;
13
+ children?: (data: Signal<{
14
+ value: T;
15
+ pos: PositionProps;
16
+ }>) => JSX.DOMNode;
17
+ }
18
+ export declare function ForWithPosition<T>({ of, children: render, separator }: ForWithPositionProps<T>): JSX.DOMNode;
package/components/For.js CHANGED
@@ -5,10 +5,22 @@ import { OnRemove } from './OnRemove';
5
5
  // <For of={values} separator={() => ", "}>{(value) => <span>{value}</span>}</For>
6
6
  export function For({ of, children: render, separator }) {
7
7
  const times = of.map(v => v.length);
8
- return new RepeatImpl(times, (index) => {
9
- const value = of.at(index);
8
+ return new RepeatImpl(times, (pos) => {
9
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
10
+ const value = of.combine(pos, (arr, { index }) => arr.at(index));
10
11
  return new FragmentImpl([
11
- makeRenderable(render?.(value, index)),
12
+ makeRenderable(render?.(value, pos)),
13
+ OnRemove({ clear: value.clean })
14
+ ]);
15
+ }, separator);
16
+ }
17
+ export function ForWithPosition({ of, children: render, separator }) {
18
+ const times = of.map(v => v.length);
19
+ return new RepeatImpl(times, (pos) => {
20
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
21
+ const value = of.combine(pos, (arr, { index }) => arr.at(index));
22
+ return new FragmentImpl([
23
+ makeRenderable(render?.(value.combine(pos, (v, p) => ({ value: v, pos: p })))),
12
24
  OnRemove({ clear: value.clean })
13
25
  ]);
14
26
  }, separator);
@@ -1,4 +1,4 @@
1
1
  import { LifecycleImpl } from './Lifecycle';
2
2
  export function OnRemove(props) {
3
- return new LifecycleImpl(() => { }, (_, removeTree) => props.clear(removeTree));
3
+ return new LifecycleImpl(() => { }, (_, removeTree) => { props.clear(removeTree); });
4
4
  }
@@ -37,24 +37,24 @@ export declare function OneOfUnion<T extends {
37
37
  [_ in K]: string;
38
38
  }, K extends string>(props: OneOfUnionProps<T, K>): JSX.DOMNode;
39
39
  export type OneOfUnionTypeProps<T extends {
40
- [_ in "type"]: string;
40
+ [_ in 'type']: string;
41
41
  }> = {
42
42
  match: Signal<T>;
43
43
  } & {
44
- [KK in T["type"]]: (value: Signal<T extends {
45
- [_ in "type"]: KK;
44
+ [KK in T['type']]: (value: Signal<T extends {
45
+ [_ in 'type']: KK;
46
46
  } ? T : never>) => JSX.DOMNode;
47
47
  };
48
48
  export declare function OneOfUnionType<T extends {
49
49
  type: string;
50
50
  }>(props: OneOfUnionTypeProps<T>): JSX.DOMNode;
51
51
  export type OneOfUnionKindProps<T extends {
52
- [_ in "kind"]: string;
52
+ [_ in 'kind']: string;
53
53
  }> = {
54
54
  match: Signal<T>;
55
55
  } & {
56
- [KK in T["kind"]]: (value: Signal<T extends {
57
- [_ in "kind"]: KK;
56
+ [KK in T['kind']]: (value: Signal<T extends {
57
+ [_ in 'kind']: KK;
58
58
  } ? T : never>) => JSX.DOMNode;
59
59
  };
60
60
  export declare function OneOfUnionKind<T extends {
@@ -50,16 +50,19 @@ export function OneOfLiteral(props) {
50
50
  const obj = keys.reduce((acc, k) => {
51
51
  acc[k] = () => cases[k];
52
52
  return acc;
53
+ // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter, @typescript-eslint/consistent-type-assertions
53
54
  }, {});
54
- return new OneOfImpl(match.map(k => ({ [k]: null })), obj);
55
+ return new OneOfImpl(
56
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
57
+ match.map(k => ({ [k]: null })), obj);
55
58
  }
56
59
  export function OneOfUnion(props) {
57
60
  const { match, using, ...cases } = props;
58
61
  return new OneOfImpl(match.map(t => ({ [t[using]]: t })), cases);
59
62
  }
60
63
  export function OneOfUnionType(props) {
61
- return OneOfUnion({ ...props, using: "type" });
64
+ return OneOfUnion({ ...props, using: 'type' });
62
65
  }
63
66
  export function OneOfUnionKind(props) {
64
- return OneOfUnion({ ...props, using: "kind" });
67
+ return OneOfUnion({ ...props, using: 'kind' });
65
68
  }
@@ -1,26 +1,28 @@
1
- import { Signal } from '../prop';
1
+ /** @jsxImportSource .. */
2
+ import { type Signal } from '../prop';
2
3
  import { type Clear } from '../clean';
3
4
  import { type DOMContext } from '../dom-context';
4
5
  import { type Renderable } from '../renderable';
5
- import { JSX } from '../jsx';
6
- export interface SeparatorProps {
7
- first: boolean;
8
- last: boolean;
9
- index: number;
6
+ import { type JSX } from '../jsx';
7
+ export interface PositionProps {
8
+ readonly first: boolean;
9
+ readonly last: boolean;
10
+ readonly index: number;
10
11
  }
12
+ export declare function makePosition(index: number, length: number): PositionProps;
11
13
  export declare class RepeatImpl implements Renderable {
12
14
  private readonly times;
13
15
  private readonly children;
14
16
  private readonly separator?;
15
- constructor(times: Signal<number>, children: (index: number) => JSX.DOMNode, separator?: ((sep: Signal<SeparatorProps>) => JSX.DOMNode) | undefined);
17
+ constructor(times: Signal<number>, children: (pos: Signal<PositionProps>) => JSX.DOMNode, separator?: ((sep: Signal<PositionProps>) => JSX.DOMNode) | undefined);
16
18
  readonly appendTo: (ctx: DOMContext) => Clear;
17
19
  readonly appendToWithoutSeparator: (ctx: DOMContext) => Clear;
18
- readonly appendToWithSeparator: (ctx: DOMContext, separator: (sep: Signal<SeparatorProps>) => JSX.DOMNode) => Clear;
20
+ readonly appendToWithSeparator: (ctx: DOMContext, separator: (sep: Signal<PositionProps>) => JSX.DOMNode) => Clear;
19
21
  }
20
22
  export interface RepeatProps {
21
23
  times: Signal<number>;
22
- children?: (index: number) => JSX.DOMNode;
23
- separator?: (sep: Signal<SeparatorProps>) => JSX.DOMNode;
24
+ children?: (pos: Signal<PositionProps>) => JSX.DOMNode;
25
+ separator?: (sep: Signal<PositionProps>) => JSX.DOMNode;
24
26
  }
25
27
  export declare function Repeat(props: RepeatProps): Renderable;
26
- export declare function conjuctions(other: JSX.DOMNode, lastConjunction?: JSX.DOMNode, firstConjunction?: JSX.DOMNode): (sep: Signal<SeparatorProps>) => JSX.DOMNode;
28
+ export declare function conjuctions(other: JSX.DOMNode, lastConjunction?: JSX.DOMNode, firstConjunction?: JSX.DOMNode): (sep: Signal<PositionProps>) => JSX.DOMNode;
@@ -1,6 +1,16 @@
1
+ import { jsx as _jsx } from "../jsx-runtime";
2
+ /** @jsxImportSource .. */
1
3
  import { Prop } from '../prop';
2
4
  import { Fragment } from './Fragment';
3
5
  import { makeRenderable } from '../jsx-runtime';
6
+ import { OneOf } from './OneOf';
7
+ export function makePosition(index, length) {
8
+ return {
9
+ first: index === 0,
10
+ last: index === length - 1,
11
+ index
12
+ };
13
+ }
4
14
  export class RepeatImpl {
5
15
  times;
6
16
  children;
@@ -11,7 +21,7 @@ export class RepeatImpl {
11
21
  this.separator = separator;
12
22
  }
13
23
  appendTo = (ctx) => {
14
- if (!this.separator) {
24
+ if (this.separator == null) {
15
25
  return this.appendToWithoutSeparator(ctx);
16
26
  }
17
27
  else {
@@ -22,16 +32,24 @@ export class RepeatImpl {
22
32
  const newCtx = ctx.makeReference();
23
33
  const count = this.times.get();
24
34
  const clears = new Array(count);
35
+ const positions = new Array(count);
25
36
  for (let i = 0; i < count; i++) {
26
- clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
37
+ positions[i] = new Prop(makePosition(i, count));
38
+ clears[i] = makeRenderable(this.children(positions[i])).appendTo(newCtx);
27
39
  }
28
40
  const cancel = this.times.subscribe((newCount) => {
29
41
  while (newCount < clears.length) {
30
42
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31
43
  clears.pop()(true);
44
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
45
+ positions.pop().clean();
46
+ }
47
+ for (let i = 0; i < positions.length; i++) {
48
+ positions[i].set(makePosition(i, newCount));
32
49
  }
33
50
  for (let i = clears.length; i < newCount; i++) {
34
- clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
51
+ positions[i] = new Prop(makePosition(i, count));
52
+ clears[i] = makeRenderable(this.children(positions[i])).appendTo(newCtx);
35
53
  }
36
54
  });
37
55
  return (removeTree) => {
@@ -47,8 +65,10 @@ export class RepeatImpl {
47
65
  const separatorProps = new Array(Math.max(0, count - 1));
48
66
  const separatorClears = new Array(Math.max(0, count - 1));
49
67
  const clears = new Array(count);
68
+ const positions = new Array(count);
50
69
  for (let i = 0; i < count; i++) {
51
- clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
70
+ positions[i] = new Prop(makePosition(i, count));
71
+ clears[i] = makeRenderable(this.children(positions[i])).appendTo(newCtx);
52
72
  if (i < count - 1) {
53
73
  separatorProps[i] = Prop.of({
54
74
  first: i === 0,
@@ -62,6 +82,8 @@ export class RepeatImpl {
62
82
  while (newCount < clears.length) {
63
83
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
64
84
  clears.pop()(true);
85
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
86
+ positions.pop().clean();
65
87
  if (separatorClears.length > 0) {
66
88
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67
89
  separatorClears.pop()(true);
@@ -69,6 +91,9 @@ export class RepeatImpl {
69
91
  separatorProps.pop().clean();
70
92
  }
71
93
  }
94
+ for (let i = 0; i < positions.length; i++) {
95
+ positions[i].set(makePosition(i, newCount));
96
+ }
72
97
  for (let i = 0; i < separatorProps.length; i++) {
73
98
  separatorProps[i].set({
74
99
  first: i === 0,
@@ -77,7 +102,8 @@ export class RepeatImpl {
77
102
  });
78
103
  }
79
104
  for (let i = clears.length; i < newCount; i++) {
80
- clears[i] = makeRenderable(this.children(i)).appendTo(newCtx);
105
+ positions[i] = new Prop(makePosition(i, count));
106
+ clears[i] = makeRenderable(this.children(positions[i])).appendTo(newCtx);
81
107
  if (i < newCount - 1) {
82
108
  separatorProps[i] = Prop.of({
83
109
  first: i === 0,
@@ -103,16 +129,16 @@ export function Repeat(props) {
103
129
  }
104
130
  export function conjuctions(other, lastConjunction, firstConjunction) {
105
131
  return (sep) => {
106
- return sep.map(({ first, last }) => {
107
- if (last) {
108
- return lastConjunction ?? other;
109
- }
110
- else if (first) {
111
- return firstConjunction ?? other;
112
- }
113
- else {
114
- return other;
115
- }
116
- });
132
+ return _jsx(OneOf, { match: sep.map(({ first, last }) => {
133
+ if (last) {
134
+ return { last: true };
135
+ }
136
+ else if (first) {
137
+ return { first: true };
138
+ }
139
+ else {
140
+ return { other: true };
141
+ }
142
+ }), first: () => firstConjunction ?? other, last: () => lastConjunction ?? other, other: () => other });
117
143
  };
118
144
  }
@@ -1,17 +1,17 @@
1
1
  export function parseColorChannels(color) {
2
2
  let match = color.match(/rgba?\((\d+), (\d+), (\d+)(, (\d+))?\)/);
3
- if (match) {
3
+ if (match != null) {
4
4
  return [
5
5
  Number(match[1]),
6
6
  Number(match[2]),
7
7
  Number(match[3]),
8
- match[4] ? Number(match[5]) : 1,
8
+ match[4] != null ? Number(match[5]) : 1,
9
9
  'rgba'
10
10
  ];
11
11
  }
12
12
  else {
13
13
  match = color.match(/#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/);
14
- if (match) {
14
+ if (match != null) {
15
15
  return [
16
16
  parseInt(match[1], 16),
17
17
  parseInt(match[2], 16),
@@ -22,12 +22,12 @@ export function parseColorChannels(color) {
22
22
  }
23
23
  else {
24
24
  match = color.match(/hsla?\((\d+), (\d+)%?, (\d+)%?(, (\d+))?\)/);
25
- if (match) {
25
+ if (match != null) {
26
26
  return [
27
27
  Number(match[1]),
28
28
  Number(match[2]),
29
29
  Number(match[3]),
30
- match[4] ? Number(match[5]) : 1,
30
+ match[4] != null ? Number(match[5]) : 1,
31
31
  'hsla'
32
32
  ];
33
33
  }
@@ -38,7 +38,7 @@ export function parseColorChannels(color) {
38
38
  function parseBoxShadow(cssString) {
39
39
  const boxShadowRegex = /^(inset\s)?(-?\d+)([a-zA-Z]*)(\s+)(-?\d+)([a-zA-Z]*)(?:\s+(-?\d+)([a-zA-Z]*))?(?:\s+(-?\d+)([a-zA-Z]*))?(?:\s+(-?\d+)([a-zA-Z]*))?(?:\s+)([a-zA-Z0-9(),.]+)$/i;
40
40
  const match = cssString.match(boxShadowRegex);
41
- if (!match) {
41
+ if (match == null) {
42
42
  return {
43
43
  inset: false,
44
44
  x: 0,
@@ -49,8 +49,8 @@ function parseBoxShadow(cssString) {
49
49
  };
50
50
  }
51
51
  const [, inset, x, , , y, , blur, , spread, , color] = match;
52
- const parsedBlur = blur ? parseInt(blur, 10) : 0;
53
- const parsedSpread = spread ? parseInt(spread, 10) : 0;
52
+ const parsedBlur = blur != null ? parseInt(blur, 10) : 0;
53
+ const parsedSpread = spread != null ? parseInt(spread, 10) : 0;
54
54
  return {
55
55
  inset: !!inset,
56
56
  x: parseInt(x, 10),
@@ -78,7 +78,7 @@ export function colorChannelsToString(channels) {
78
78
  }
79
79
  export function interpolateColor(startColor, endColor) {
80
80
  const [startR, startG, startB, startA, startType] = parseColorChannels(startColor);
81
- const [endR, endG, endB, endA, endType] = parseColorChannels(endColor);
81
+ const [endR, endG, endB, endA] = parseColorChannels(endColor);
82
82
  return (t) => {
83
83
  const r = startR + (endR - startR) * t;
84
84
  const g = startG + (endG - startG) * t;
@@ -234,11 +234,12 @@ export function applyAnimatableProp(el, key, value) {
234
234
  }
235
235
  const interpolationCache = new Map();
236
236
  function getInterpolate(from, to, type) {
237
- if (interpolationCache.has(type + ":" + from + to)) {
237
+ if (interpolationCache.has(type + ':' + from + to)) {
238
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
238
239
  return interpolationCache.get(from + to);
239
240
  }
240
241
  const f = interpolateColor(from, to);
241
- interpolationCache.set(type + ":" + from + to, f);
242
+ interpolationCache.set(type + ':' + from + to, f);
242
243
  return f;
243
244
  }
244
245
  function getColorInterpolation(from, to) {
package/index.d.ts CHANGED
@@ -26,7 +26,7 @@ export { OnRemove, type OnRemoveProps } from './components/OnRemove';
26
26
  export { OneOfImpl, OneOf, type OneOfProps, OneOfLiteral, type OneOfLiteralProps, OneOfUnion, type OneOfUnionProps, OneOfUnionKind, type OneOfUnionKindProps, OneOfUnionType, type OneOfUnionTypeProps } from './components/OneOf';
27
27
  export { PortalImpl, Portal, type PortalProps } from './components/Portal';
28
28
  export { PropertyImpl, Property, type PropertyProps } from './components/Property';
29
- export { RepeatImpl, Repeat, type RepeatProps, conjuctions } from './components/Repeat';
29
+ export { RepeatImpl, Repeat, type RepeatProps, conjuctions, type PositionProps } from './components/Repeat';
30
30
  export { ShowImpl, Show, type ShowProps } from './components/Show';
31
31
  export { TextImpl, Text, type TextProps } from './components/Text';
32
32
  export { TextContentImpl, TextContent, type TextContentProps } from './components/TextContent';
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tempots/dom",
3
3
  "main": "index.js",
4
4
  "types": "index.d.ts",
5
- "version": "6.0.0",
5
+ "version": "7.0.0",
6
6
  "scripts": {
7
7
  "watch": "tsc --watch",
8
8
  "build": "tsc",