solid-ctrl-flow 1.0.18 → 1.0.20

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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,31 @@
1
1
  import { Accessor } from 'solid-js';
2
2
  import { Context } from 'solid-js';
3
3
  import { JSX } from 'solid-js';
4
+ import { Setter } from 'solid-js';
5
+ import { Signal } from 'solid-js';
6
+
7
+ /**
8
+ * Creates a one-way binding between two {@link Signal}s
9
+ * @param source The source of the binding
10
+ * @param dest The destination of the binding
11
+ * @param to Conversion function from {@link S} to {@link D}
12
+ * @returns A function that disposes the binding
13
+ */
14
+ export declare function bind<S>(source: Signal<S>, dest: Signal<S>): () => void;
15
+
16
+ export declare function bind<S, D>(source: Signal<S>, dest: Signal<D>, to: Convert<S, D>): () => void;
17
+
18
+ /**
19
+ * Creates a two-way binding between two {@link Signal}s
20
+ * @param source The source of the binding
21
+ * @param dest The destination of the binding
22
+ * @param to Conversion function from {@link S} to {@link D}
23
+ * @param from Conversion function from {@link D} to {@link S}
24
+ * @returns A function that disposes the binding
25
+ */
26
+ export declare function bindTwoWay<S>(source: Signal<S>, dest: Signal<S>): () => void;
27
+
28
+ export declare function bindTwoWay<S, D>(source: Signal<S>, dest: Signal<D>, to: Convert<S, D>, from: Convert<D, S>): () => void;
4
29
 
5
30
  /**
6
31
  * Allows the use of {@link When}s inside of {@link Switch}es.
@@ -37,6 +62,9 @@ export declare function Case(props: {
37
62
  children: JSX.Element;
38
63
  }): JSX.Element;
39
64
 
65
+ /** Conversion function for bindings */
66
+ export declare type Convert<S, D> = (x: S, prev: D) => D;
67
+
40
68
  /**
41
69
  * Creates a slot that allows you to show a component outside of its parent.
42
70
  * It works with arbitrary nesting.
@@ -77,24 +105,33 @@ export declare function createExtractor(name?: string): {
77
105
 
78
106
  /**
79
107
  * Creates a context with a reactive value.
80
- * It returns the provider directly
108
+ * Returns a provider with additional fields:
109
+ * - The `read` getter, which returns an {@link Accessor} to the value
110
+ * - The `runWith()` method, which executes {@link runWithContext} on the option
81
111
  * @param init Initial value for the context
82
112
  * @param def Default value to set when calling the provider without one
83
113
  * @param name Name to give to the context
84
114
  */
85
- export declare function createOption<T>(init: T, def?: T, name?: string): ((props: {
86
- value?: T;
87
- children: JSX.Element;
88
- }) => JSX.Element) & {
115
+ export declare function createOption<T>(init: T, def?: T, name?: string): {
116
+ (props: {
117
+ value?: T;
118
+ children: JSX.Element;
119
+ }): JSX.Element;
120
+ /** Executes {@link runWithContext} on the provided option */
121
+ runWith<V extends T, R>(x: V, f: (x: V) => R): R;
122
+ } & {
89
123
  /** Returns the {@link Accessor} for the value in the current context */
90
124
  read: Accessor<T>;
91
125
  };
92
126
 
93
127
  /** Creates a scope for the value of {@link Debug.read}, which allows you to display different things in debug mode */
94
- export declare const Debug: ((props: {
95
- value?: boolean | undefined;
96
- children: JSX.Element;
97
- }) => JSX.Element) & {
128
+ export declare const Debug: {
129
+ (props: {
130
+ value?: boolean | undefined;
131
+ children: JSX.Element;
132
+ }): JSX.Element;
133
+ runWith<V extends boolean, R>(x: V, f: (x: V) => R): R;
134
+ } & {
98
135
  read: Accessor<boolean>;
99
136
  };
100
137
 
@@ -129,6 +166,20 @@ export declare function runWithContext<T, R>(ctx: Context<T>, value: T, f: (x: T
129
166
  */
130
167
  export declare function splitAndMemoProps<T extends object, K extends readonly (keyof T)[]>(obj: T, keys: K): [Pick<T, Extract<K, readonly (keyof T)[]>[number]>, Omit<T, K[number]>];
131
168
 
169
+ /**
170
+ * Creates a full-fledged solid {@link Setter} from a normal one
171
+ * @param get The getter of the {@link Signal}; It's needed when a function gets passed to the new setter
172
+ * @param set The simple setter to which to add functionalities
173
+ */
174
+ export declare function toSetter<T>(get: Accessor<T>, set: (x: T) => void): Setter<T>;
175
+
176
+ /**
177
+ * Creates a {@link Signal} from a property access
178
+ * @param obj The object from which to get the property
179
+ * @param k The key of the property
180
+ */
181
+ export declare function toSignal<T, K extends keyof T>(obj: T, k: K): Signal<T[K]>;
182
+
132
183
  /**
133
184
  * Executes {@link f} untracking it.
134
185
  * Due to the fact that the function is passed as input, it does not untrack its changes (It's intentional)
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { untrack, createMemo, splitProps, createContext, createRoot, getOwner, createComponent, useContext, Match, mergeProps, onCleanup, For, Show } from "solid-js";
1
+ import { untrack, createMemo, splitProps, createContext, createRoot, getOwner, createComponent, useContext, createEffect, on, onCleanup, Match, mergeProps, For, Show } from "solid-js";
2
2
  import { createMutable } from "solid-js/store";
3
3
  function untrackCall(f, ...args) {
4
4
  return untrack(() => f.apply(this, args));
@@ -31,6 +31,7 @@ function createOption(init, def = init, name) {
31
31
  Object.defineProperty(provider, prop, {
32
32
  get: () => useContext(ctx2)
33
33
  });
34
+ provider.runWith = (x, f) => runWithContext(ctx2, () => x, () => f(x));
34
35
  return provider;
35
36
  }
36
37
  function runWithContext(ctx2, value, f) {
@@ -48,6 +49,26 @@ function runWithContext(ctx2, value, f) {
48
49
  }
49
50
  });
50
51
  }
52
+ const IDENTITY = (x) => x;
53
+ function toSetter(get, set) {
54
+ return (x) => {
55
+ const out = typeof x === "function" ? x(untrack(get)) : x;
56
+ return set(out), out;
57
+ };
58
+ }
59
+ function toSignal(obj, k) {
60
+ const get = () => obj[k];
61
+ return [get, toSetter(get, (v) => obj[k] = v)];
62
+ }
63
+ function bind(source, dest, to = IDENTITY) {
64
+ const d = createRoot((d2) => (createEffect(on(source[0], (x) => dest[1]((prev) => to(x, prev)))), d2));
65
+ return onCleanup(d), d;
66
+ }
67
+ function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
68
+ const a = bind(source, dest, to);
69
+ const b = bind(dest, source, from);
70
+ return () => (a(), b());
71
+ }
51
72
  const ctx = createContext(() => void 0, {
52
73
  name: "case-when"
53
74
  });
@@ -148,10 +169,14 @@ export {
148
169
  Case,
149
170
  Debug,
150
171
  When,
172
+ bind,
173
+ bindTwoWay,
151
174
  createExtractor,
152
175
  createOption,
153
176
  memoProps,
154
177
  runWithContext,
155
178
  splitAndMemoProps,
179
+ toSetter,
180
+ toSignal,
156
181
  untrackCall
157
182
  };
package/dist/index.umd.js CHANGED
@@ -33,6 +33,7 @@
33
33
  Object.defineProperty(provider, prop, {
34
34
  get: () => solidJs.useContext(ctx2)
35
35
  });
36
+ provider.runWith = (x, f) => runWithContext(ctx2, () => x, () => f(x));
36
37
  return provider;
37
38
  }
38
39
  function runWithContext(ctx2, value, f) {
@@ -50,6 +51,26 @@
50
51
  }
51
52
  });
52
53
  }
54
+ const IDENTITY = (x) => x;
55
+ function toSetter(get, set) {
56
+ return (x) => {
57
+ const out = typeof x === "function" ? x(solidJs.untrack(get)) : x;
58
+ return set(out), out;
59
+ };
60
+ }
61
+ function toSignal(obj, k) {
62
+ const get = () => obj[k];
63
+ return [get, toSetter(get, (v) => obj[k] = v)];
64
+ }
65
+ function bind(source, dest, to = IDENTITY) {
66
+ const d = solidJs.createRoot((d2) => (solidJs.createEffect(solidJs.on(source[0], (x) => dest[1]((prev) => to(x, prev)))), d2));
67
+ return solidJs.onCleanup(d), d;
68
+ }
69
+ function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
70
+ const a = bind(source, dest, to);
71
+ const b = bind(dest, source, from);
72
+ return () => (a(), b());
73
+ }
53
74
  const ctx = solidJs.createContext(() => void 0, {
54
75
  name: "case-when"
55
76
  });
@@ -149,11 +170,15 @@
149
170
  exports2.Case = Case;
150
171
  exports2.Debug = Debug;
151
172
  exports2.When = When;
173
+ exports2.bind = bind;
174
+ exports2.bindTwoWay = bindTwoWay;
152
175
  exports2.createExtractor = createExtractor;
153
176
  exports2.createOption = createOption;
154
177
  exports2.memoProps = memoProps;
155
178
  exports2.runWithContext = runWithContext;
156
179
  exports2.splitAndMemoProps = splitAndMemoProps;
180
+ exports2.toSetter = toSetter;
181
+ exports2.toSignal = toSignal;
157
182
  exports2.untrackCall = untrackCall;
158
183
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
159
184
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-ctrl-flow",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "Control flow components for solid-js",
5
5
  "author": "AFatNiBBa",
6
6
  "license": "ISC",
package/readMe.md CHANGED
@@ -121,6 +121,22 @@ Notice that you can use a `Source` component without adding it to the DOM:
121
121
  return <>Something else</>
122
122
  ```
123
123
 
124
+ ## Bindings
125
+ Functions that create bindings between `Signal`s
126
+
127
+ ### `toSetter()`
128
+ Creates a full-fledged solid `Setter` from a normal one
129
+
130
+ ### `toSignal()`
131
+ Creates a `Signal` from a property of an object
132
+
133
+ ### `bind()`
134
+ Creates a one-way binding between two `Signal`s
135
+
136
+ ### `bindTwoWay()`
137
+ Creates a two-way binding between two `Signal`s
138
+
139
+
124
140
  ## Utility functions
125
141
  Utility functions needed for the components above
126
142