@preact/signals 2.0.5 → 2.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @preact/signals
2
2
 
3
+ ## 2.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#684](https://github.com/preactjs/signals/pull/684) [`a34eab2`](https://github.com/preactjs/signals/commit/a34eab2ab5a46f4ef90e05e2af6b99747191333c) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Ensure we build the thing
8
+
9
+ ## 2.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#683](https://github.com/preactjs/signals/pull/683) [`4b585a5`](https://github.com/preactjs/signals/commit/4b585a5f15300b73dc66f45effd21342e3f6e5d5) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Provide `@preact/signals/utils` package with some helpers to make working with signals easier in Preact
14
+
3
15
  ## 2.0.5
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -111,6 +111,84 @@ function Person() {
111
111
 
112
112
  This way we'll bypass checking the virtual-dom and update the DOM property directly.
113
113
 
114
+ ## Utility Components and Hooks
115
+
116
+ The `@preact/signals/utils` package provides additional utility components and hooks to make working with signals even easier.
117
+
118
+ ### Show Component
119
+
120
+ The `Show` component provides a declarative way to conditionally render content based on a signal's value.
121
+
122
+ ```js
123
+ import { Show } from "@preact/signals/utils";
124
+ import { signal } from "@preact/signals";
125
+
126
+ const isVisible = signal(false);
127
+
128
+ function App() {
129
+ return (
130
+ <Show when={isVisible} fallback={<p>Nothing to see here</p>}>
131
+ <p>Now you see me!</p>
132
+ </Show>
133
+ );
134
+ }
135
+
136
+ // You can also use a function to access the value
137
+ function App() {
138
+ return <Show when={isVisible}>{value => <p>The value is {value}</p>}</Show>;
139
+ }
140
+ ```
141
+
142
+ ### For Component
143
+
144
+ The `For` component helps you render lists from signal arrays with automatic caching of rendered items.
145
+
146
+ ```js
147
+ import { For } from "@preact/signals/utils";
148
+ import { signal } from "@preact/signals";
149
+
150
+ const items = signal(["A", "B", "C"]);
151
+
152
+ function App() {
153
+ return (
154
+ <For each={items} fallback={<p>No items</p>}>
155
+ {(item, index) => <div key={index}>Item: {item}</div>}
156
+ </For>
157
+ );
158
+ }
159
+ ```
160
+
161
+ ### Additional Hooks
162
+
163
+ #### useLiveSignal
164
+
165
+ The `useLiveSignal` hook allows you to create a local signal that stays synchronized with an external signal.
166
+
167
+ ```js
168
+ import { useLiveSignal } from "@preact/signals/utils";
169
+ import { signal } from "@preact/signals";
170
+
171
+ const external = signal(0);
172
+
173
+ function Component() {
174
+ const local = useLiveSignal(external);
175
+ // local will automatically update when external changes
176
+ }
177
+ ```
178
+
179
+ #### useSignalRef
180
+
181
+ The `useSignalRef` hook creates a signal that behaves like a React ref with a `.current` property.
182
+
183
+ ```js
184
+ import { useSignalRef } from "@preact/signals/utils";
185
+
186
+ function Component() {
187
+ const ref = useSignalRef(null);
188
+ return <div ref={ref}>The ref's value is {ref.current}</div>;
189
+ }
190
+ ```
191
+
114
192
  ## License
115
193
 
116
194
  `MIT`, see the [LICENSE](../../LICENSE) file.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preact/signals",
3
- "version": "2.0.5",
3
+ "version": "2.1.1",
4
4
  "license": "MIT",
5
5
  "description": "Manage state with style in Preact",
6
6
  "keywords": [],
@@ -30,6 +30,12 @@
30
30
  "browser": "./dist/signals.module.js",
31
31
  "import": "./dist/signals.mjs",
32
32
  "require": "./dist/signals.js"
33
+ },
34
+ "./utils": {
35
+ "types": "./utils/dist/index.d.ts",
36
+ "browser": "./utils/dist/utils.module.js",
37
+ "import": "./utils/dist/utils.mjs",
38
+ "require": "./utils/dist/utils.js"
33
39
  }
34
40
  },
35
41
  "mangle": "../../mangle.json",
@@ -38,7 +44,10 @@
38
44
  "dist",
39
45
  "CHANGELOG.md",
40
46
  "LICENSE",
41
- "README.md"
47
+ "README.md",
48
+ "utils/dist",
49
+ "utils/package.json",
50
+ "utils/src"
42
51
  ],
43
52
  "dependencies": {
44
53
  "@preact/signals-core": "^1.7.0"
@@ -0,0 +1,19 @@
1
+ import { ReadonlySignal, Signal } from "@preact/signals-core";
2
+ import { JSX } from "preact";
3
+ interface ShowProps<T = boolean> {
4
+ when: Signal<T> | ReadonlySignal<T>;
5
+ fallback?: JSX.Element;
6
+ children: JSX.Element | ((value: T) => JSX.Element);
7
+ }
8
+ export declare function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null;
9
+ interface ForProps<T> {
10
+ each: Signal<Array<T>> | ReadonlySignal<Array<T>> | (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);
11
+ fallback?: JSX.Element;
12
+ children: (value: T, index: number) => JSX.Element;
13
+ }
14
+ export declare function For<T>(props: ForProps<T>): JSX.Element | null;
15
+ export declare function useLiveSignal<T>(value: Signal<T> | ReadonlySignal<T>): Signal<Signal<T> | ReadonlySignal<T>>;
16
+ export declare function useSignalRef<T>(value: T): Signal<T> & {
17
+ current: T;
18
+ };
19
+ export {};
@@ -0,0 +1 @@
1
+ var r=require("@preact/signals"),n=require("preact"),t=require("preact/hooks"),e={configurable:!0,get:function(){return this.value},set:function(r){this.value=r}};exports.For=function(r){var e=t.useMemo(function(){return new Map},[]),u=("function"==typeof r.each?r.each():r.each).value;if(!u.length)return r.fallback||null;var i=u.map(function(n,t){if(!e.has(n))e.set(n,r.children(n,t));return e.get(n)});return n.createElement(n.Fragment,null,i)};exports.Show=function(r){var n=r.when.value;if(!n)return r.fallback||null;else return"function"==typeof r.children?r.children(n):r.children};exports.useLiveSignal=function(n){var t=r.useSignal(n);if(t.peek()!==n)t.value=n;return t};exports.useSignalRef=function(n){var t=r.useSignal(n);if(!("current"in t))Object.defineProperty(t,"current",e);return t};//# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sources":["../src/index.ts"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals\";\nimport { Fragment, createElement, JSX } from \"preact\";\nimport { useMemo } from \"preact/hooks\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T>;\n\tfallback?: JSX.Element;\n\tchildren: JSX.Element | ((value: T) => JSX.Element);\n}\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tconst value = props.when.value;\n\tif (!value) return props.fallback || null;\n\treturn typeof props.children === \"function\"\n\t\t? props.children(value)\n\t\t: props.children;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: JSX.Element;\n\tchildren: (value: T, index: number) => JSX.Element;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return props.fallback || null;\n\n\tconst items = list.map((value, key) => {\n\t\tif (!cache.has(value)) {\n\t\t\tcache.set(value, props.children(value, key));\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\treturn createElement(Fragment, null, items);\n}\n\nexport function useLiveSignal<T>(\n\tvalue: Signal<T> | ReadonlySignal<T>\n): Signal<Signal<T> | ReadonlySignal<T>> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T): Signal<T> & { current: T } {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["signals","require","preact","hooks","refSignalProto","configurable","get","this","value","set","v","exports","For","props","cache","useMemo","Map","list","each","length","fallback","items","map","key","has","children","createElement","Fragment","Show","when","useLiveSignal","s","useSignal","peek","useSignalRef","ref","Object","defineProperty"],"mappings":"AAWM,IAAAA,EAAAC,QAAA,mBAAAC,EAAAD,QAAA,UAAAE,EAAAF,QAAA,gBAmDAG,EAAiB,CACtBC,cAAc,EACdC,IAAGA,WACF,OAAWC,KAACC,KACb,EACAC,aAAkBC,GACjBH,KAAKC,MAAQE,CACd,GACAC,QAAAC,IA1CK,SAAiBC,GACtB,IAAMC,EAAQC,EAAAA,QAAQ,WAAM,OAAA,IAAIC,GAAK,EAAE,IACnCC,GACoB,mBAAfJ,EAAMK,KAAsBL,EAAMK,OAASL,EAAMK,MAGxDV,MAEF,IAAKS,EAAKE,OAAQ,OAAON,EAAMO,UAAY,KAE3C,IAAMC,EAAQJ,EAAKK,IAAI,SAACd,EAAOe,GAC9B,IAAKT,EAAMU,IAAIhB,GACdM,EAAML,IAAID,EAAOK,EAAMY,SAASjB,EAAOe,IAExC,OAAOT,EAAMR,IAAIE,EAClB,GAEA,OAAOkB,EAAAA,cAAcC,EAAAA,SAAU,KAAMN,EACtC,EAwBCV,QAAAiB,KA3DK,SAA4Bf,GACjC,IAAML,EAAQK,EAAMgB,KAAKrB,MACzB,IAAKA,EAAO,OAAOK,EAAMO,UAAY,UACrC,MAAiC,mBAAnBP,EAAMY,SACjBZ,EAAMY,SAASjB,GACfK,EAAMY,QACV,EAqDCd,QAAAmB,cAtBK,SACLtB,GAEA,IAAMuB,EAAIC,EAASA,UAACxB,GACpB,GAAIuB,EAAEE,SAAWzB,EAAOuB,EAAEvB,MAAQA,EAClC,OAAOuB,CACR,EAgBCpB,QAAAuB,aAdK,SAA0B1B,GAC/B,IAAM2B,EAAMH,EAASA,UAACxB,GACtB,KAAM,YAAa2B,GAClBC,OAAOC,eAAeF,EAAK,UAAW/B,GACvC,OAAO+B,CACR"}
@@ -0,0 +1 @@
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@preact/signals"),require("preact"),require("preact/hooks")):"function"==typeof define&&define.amd?define(["exports","@preact/signals","preact","preact/hooks"],n):n((e||self).preactSignalsutils={},e.signals,e.preact,e.preactHooks)}(this,function(e,n,t,r){var i={configurable:!0,get:function(){return this.value},set:function(e){this.value=e}};e.For=function(e){var n=r.useMemo(function(){return new Map},[]),i=("function"==typeof e.each?e.each():e.each).value;if(!i.length)return e.fallback||null;var u=i.map(function(t,r){if(!n.has(t))n.set(t,e.children(t,r));return n.get(t)});return t.createElement(t.Fragment,null,u)};e.Show=function(e){var n=e.when.value;if(!n)return e.fallback||null;else return"function"==typeof e.children?e.children(n):e.children};e.useLiveSignal=function(e){var t=n.useSignal(e);if(t.peek()!==e)t.value=e;return t};e.useSignalRef=function(e){var t=n.useSignal(e);if(!("current"in t))Object.defineProperty(t,"current",i);return t}});//# sourceMappingURL=utils.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.min.js","sources":["../src/index.ts"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals\";\nimport { Fragment, createElement, JSX } from \"preact\";\nimport { useMemo } from \"preact/hooks\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T>;\n\tfallback?: JSX.Element;\n\tchildren: JSX.Element | ((value: T) => JSX.Element);\n}\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tconst value = props.when.value;\n\tif (!value) return props.fallback || null;\n\treturn typeof props.children === \"function\"\n\t\t? props.children(value)\n\t\t: props.children;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: JSX.Element;\n\tchildren: (value: T, index: number) => JSX.Element;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return props.fallback || null;\n\n\tconst items = list.map((value, key) => {\n\t\tif (!cache.has(value)) {\n\t\t\tcache.set(value, props.children(value, key));\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\treturn createElement(Fragment, null, items);\n}\n\nexport function useLiveSignal<T>(\n\tvalue: Signal<T> | ReadonlySignal<T>\n): Signal<Signal<T> | ReadonlySignal<T>> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T): Signal<T> & { current: T } {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["g","f","exports","module","require","define","amd","globalThis","self","preactSignalsutils","signals","preact","preactHooks","this","hooks","refSignalProto","configurable","get","value","set","v","For","props","cache","useMemo","Map","list","each","length","fallback","items","map","key","has","children","createElement","Fragment","Show","when","useLiveSignal","s","useSignal","peek","useSignalRef","ref","Object","defineProperty"],"mappings":"CAWM,SAAAA,EAAAC,GAAA,iBAAAC,SAAA,oBAAAC,OAAAF,EAAAC,QAAAE,QAAA,mBAAAA,QAAA,UAAAA,QAAA,iBAAA,mBAAAC,QAAAA,OAAAC,IAAAD,OAAA,CAAA,UAAA,kBAAA,SAAA,gBAAAJ,GAAAA,GAAAD,EAAA,oBAAAO,WAAAA,WAAAP,GAAAQ,MAAAC,mBAAA,CAAA,EAAAT,EAAAU,QAAAV,EAAAW,OAAAX,EAAAY,YAAA,CAAA,CAAAC,KAAA,SAAAX,EAAAQ,EAAAC,EAAAG,GAmDN,IAAMC,EAAiB,CACtBC,cAAc,EACdC,IAAGA,WACF,OAAWJ,KAACK,KACb,EACAC,aAAkBC,GACjBP,KAAKK,MAAQE,CACd,GACAlB,EAAAmB,IA1CK,SAAiBC,GACtB,IAAMC,EAAQC,EAAAA,QAAQ,WAAM,OAAA,IAAIC,GAAK,EAAE,IACnCC,GACoB,mBAAfJ,EAAMK,KAAsBL,EAAMK,OAASL,EAAMK,MAGxDT,MAEF,IAAKQ,EAAKE,OAAQ,OAAON,EAAMO,UAAY,KAE3C,IAAMC,EAAQJ,EAAKK,IAAI,SAACb,EAAOc,GAC9B,IAAKT,EAAMU,IAAIf,GACdK,EAAMJ,IAAID,EAAOI,EAAMY,SAAShB,EAAOc,IAExC,OAAOT,EAAMN,IAAIC,EAClB,GAEA,OAAOiB,EAAAA,cAAcC,EAAAA,SAAU,KAAMN,EACtC,EAwBC5B,EAAAmC,KA3DK,SAA4Bf,GACjC,IAAMJ,EAAQI,EAAMgB,KAAKpB,MACzB,IAAKA,EAAO,OAAOI,EAAMO,UAAY,UACrC,MAAiC,mBAAnBP,EAAMY,SACjBZ,EAAMY,SAAShB,GACfI,EAAMY,QACV,EAqDChC,EAAAqC,cAtBK,SACLrB,GAEA,IAAMsB,EAAIC,EAASA,UAACvB,GACpB,GAAIsB,EAAEE,SAAWxB,EAAOsB,EAAEtB,MAAQA,EAClC,OAAOsB,CACR,EAgBCtC,EAAAyC,aAdK,SAA0BzB,GAC/B,IAAM0B,EAAMH,EAASA,UAACvB,GACtB,KAAM,YAAa0B,GAClBC,OAAOC,eAAeF,EAAK,UAAW7B,GACvC,OAAO6B,CACR,CASC"}
@@ -0,0 +1 @@
1
+ import{useSignal}from"@preact/signals";import{createElement as t,Fragment as n}from"preact";import{useMemo as r}from"preact/hooks";function e(t){const n=t.when.value;if(!n)return t.fallback||null;else return"function"==typeof t.children?t.children(n):t.children}function o(e){const o=r(()=>new Map,[]);let u=("function"==typeof e.each?e.each():e.each).value;if(!u.length)return e.fallback||null;const c=u.map((t,n)=>{if(!o.has(t))o.set(t,e.children(t,n));return o.get(t)});return t(n,null,c)}function u(t){const n=useSignal(t);if(n.peek()!==t)n.value=t;return n}function c(t){const n=useSignal(t);if(!("current"in n))Object.defineProperty(n,"current",i);return n}const i={configurable:!0,get(){return this.value},set(t){this.value=t}};export{o as For,e as Show,u as useLiveSignal,c as useSignalRef};//# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","sources":["../src/index.ts"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals\";\nimport { Fragment, createElement, JSX } from \"preact\";\nimport { useMemo } from \"preact/hooks\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T>;\n\tfallback?: JSX.Element;\n\tchildren: JSX.Element | ((value: T) => JSX.Element);\n}\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tconst value = props.when.value;\n\tif (!value) return props.fallback || null;\n\treturn typeof props.children === \"function\"\n\t\t? props.children(value)\n\t\t: props.children;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: JSX.Element;\n\tchildren: (value: T, index: number) => JSX.Element;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return props.fallback || null;\n\n\tconst items = list.map((value, key) => {\n\t\tif (!cache.has(value)) {\n\t\t\tcache.set(value, props.children(value, key));\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\treturn createElement(Fragment, null, items);\n}\n\nexport function useLiveSignal<T>(\n\tvalue: Signal<T> | ReadonlySignal<T>\n): Signal<Signal<T> | ReadonlySignal<T>> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T): Signal<T> & { current: T } {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["Show","props","value","when","fallback","children","For","cache","useMemo","Map","list","each","length","items","map","key","has","set","get","createElement","Fragment","useLiveSignal","s","useSignal","peek","useSignalRef","ref","Object","defineProperty","refSignalProto","configurable","this","v"],"mappings":"mIAWM,SAAUA,EAAkBC,GACjC,MAAMC,EAAQD,EAAME,KAAKD,MACzB,IAAKA,EAAO,OAAOD,EAAMG,UAAY,UACrC,MAAiC,mBAAnBH,EAAMI,SACjBJ,EAAMI,SAASH,GACfD,EAAMI,QACV,CAWgB,SAAAC,EAAOL,GACtB,MAAMM,EAAQC,EAAQ,IAAM,IAAIC,IAAO,IACvC,IAAIC,GACoB,mBAAfT,EAAMU,KAAsBV,EAAMU,OAASV,EAAMU,MAGxDT,MAEF,IAAKQ,EAAKE,OAAQ,OAAOX,EAAMG,UAAY,KAE3C,MAAMS,EAAQH,EAAKI,IAAI,CAACZ,EAAOa,KAC9B,IAAKR,EAAMS,IAAId,GACdK,EAAMU,IAAIf,EAAOD,EAAMI,SAASH,EAAOa,IAExC,OAAOR,EAAMW,IAAIhB,EAAK,GAGvB,OAAOiB,EAAcC,EAAU,KAAMP,EACtC,UAEgBQ,EACfnB,GAEA,MAAMoB,EAAIC,UAAUrB,GACpB,GAAIoB,EAAEE,SAAWtB,EAAOoB,EAAEpB,MAAQA,EAClC,OAAOoB,CACR,CAEgB,SAAAG,EAAgBvB,GAC/B,MAAMwB,EAAMH,UAAUrB,GACtB,KAAM,YAAawB,GAClBC,OAAOC,eAAeF,EAAK,UAAWG,GACvC,OAAOH,CACR,CACA,MAAMG,EAAiB,CACtBC,cAAc,EACdZ,MACC,OAAOa,KAAK7B,KACb,EACAe,IAAkBe,GACjBD,KAAK7B,MAAQ8B,CACd,UACA1B,SAAAN,UAAAqB,mBAAAI"}
@@ -0,0 +1 @@
1
+ import{useSignal}from"@preact/signals";import{createElement as r,Fragment as n}from"preact";import{useMemo as t}from"preact/hooks";function u(r){var n=r.when.value;if(!n)return r.fallback||null;else return"function"==typeof r.children?r.children(n):r.children}function e(u){var e=t(function(){return new Map},[]),i=("function"==typeof u.each?u.each():u.each).value;if(!i.length)return u.fallback||null;var o=i.map(function(r,n){if(!e.has(r))e.set(r,u.children(r,n));return e.get(r)});return r(n,null,o)}function i(r){var n=useSignal(r);if(n.peek()!==r)n.value=r;return n}function o(r){var n=useSignal(r);if(!("current"in n))Object.defineProperty(n,"current",f);return n}var f={configurable:!0,get:function(){return this.value},set:function(r){this.value=r}};export{e as For,u as Show,i as useLiveSignal,o as useSignalRef};//# sourceMappingURL=utils.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.module.js","sources":["../src/index.ts"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals\";\nimport { Fragment, createElement, JSX } from \"preact\";\nimport { useMemo } from \"preact/hooks\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T>;\n\tfallback?: JSX.Element;\n\tchildren: JSX.Element | ((value: T) => JSX.Element);\n}\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tconst value = props.when.value;\n\tif (!value) return props.fallback || null;\n\treturn typeof props.children === \"function\"\n\t\t? props.children(value)\n\t\t: props.children;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: JSX.Element;\n\tchildren: (value: T, index: number) => JSX.Element;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return props.fallback || null;\n\n\tconst items = list.map((value, key) => {\n\t\tif (!cache.has(value)) {\n\t\t\tcache.set(value, props.children(value, key));\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\treturn createElement(Fragment, null, items);\n}\n\nexport function useLiveSignal<T>(\n\tvalue: Signal<T> | ReadonlySignal<T>\n): Signal<Signal<T> | ReadonlySignal<T>> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T): Signal<T> & { current: T } {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["useSignal","createElement","Fragment","useMemo","Show","props","value","when","fallback","children","For","cache","Map","list","each","length","items","map","key","has","set","get","useLiveSignal","s","peek","useSignalRef","ref","Object","defineProperty","refSignalProto","configurable","this","v"],"mappings":"OAWMA,cAAA,0CAAAC,cAAAC,MAAA,2BAAAC,MAAA,eAAA,SAAUC,EAAkBC,GACjC,IAAMC,EAAQD,EAAME,KAAKD,MACzB,IAAKA,EAAO,OAAOD,EAAMG,UAAY,UACrC,MAAiC,mBAAnBH,EAAMI,SACjBJ,EAAMI,SAASH,GACfD,EAAMI,QACV,CAWM,SAAUC,EAAOL,GACtB,IAAMM,EAAQR,EAAQ,WAAM,OAAA,IAAIS,GAAK,EAAE,IACnCC,GACoB,mBAAfR,EAAMS,KAAsBT,EAAMS,OAAST,EAAMS,MAGxDR,MAEF,IAAKO,EAAKE,OAAQ,OAAOV,EAAMG,UAAY,KAE3C,IAAMQ,EAAQH,EAAKI,IAAI,SAACX,EAAOY,GAC9B,IAAKP,EAAMQ,IAAIb,GACdK,EAAMS,IAAId,EAAOD,EAAMI,SAASH,EAAOY,IAExC,OAAOP,EAAMU,IAAIf,EAClB,GAEA,OAAOL,EAAcC,EAAU,KAAMc,EACtC,CAEM,SAAUM,EACfhB,GAEA,IAAMiB,EAAIvB,UAAUM,GACpB,GAAIiB,EAAEC,SAAWlB,EAAOiB,EAAEjB,MAAQA,EAClC,OAAOiB,CACR,CAEM,SAAUE,EAAgBnB,GAC/B,IAAMoB,EAAM1B,UAAUM,GACtB,KAAM,YAAaoB,GAClBC,OAAOC,eAAeF,EAAK,UAAWG,GACvC,OAAOH,CACR,CACA,IAAMG,EAAiB,CACtBC,cAAc,EACdT,IAAGA,WACF,OAAWU,KAACzB,KACb,EACAc,aAAkBY,GACjBD,KAAKzB,MAAQ0B,CACd,UACAtB,SAAAN,UAAAkB,mBAAAG"}
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@preact/signals-utils",
3
+ "description": "Sub package for @preact/signals that contains some useful utilities",
4
+ "private": true,
5
+ "amdName": "preactSignalsutils",
6
+ "main": "dist/utils.js",
7
+ "module": "dist/utils.module.js",
8
+ "unpkg": "dist/utils.min.js",
9
+ "types": "dist/index.d.ts",
10
+ "source": "src/index.ts",
11
+ "mangle": "../../../mangle.json",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "browser": "./dist/utils.module.js",
16
+ "import": "./dist/utils.mjs",
17
+ "require": "./dist/utils.js"
18
+ }
19
+ },
20
+ "dependencies": {
21
+ "@preact/signals-core": "workspace:^1.3.0"
22
+ },
23
+ "peerDependencies": {
24
+ "@preact/signals": "workspace:*",
25
+ "preact": ">= 10.25.0"
26
+ }
27
+ }
@@ -0,0 +1,71 @@
1
+ import { ReadonlySignal, Signal } from "@preact/signals-core";
2
+ import { useSignal } from "@preact/signals";
3
+ import { Fragment, createElement, JSX } from "preact";
4
+ import { useMemo } from "preact/hooks";
5
+
6
+ interface ShowProps<T = boolean> {
7
+ when: Signal<T> | ReadonlySignal<T>;
8
+ fallback?: JSX.Element;
9
+ children: JSX.Element | ((value: T) => JSX.Element);
10
+ }
11
+
12
+ export function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {
13
+ const value = props.when.value;
14
+ if (!value) return props.fallback || null;
15
+ return typeof props.children === "function"
16
+ ? props.children(value)
17
+ : props.children;
18
+ }
19
+
20
+ interface ForProps<T> {
21
+ each:
22
+ | Signal<Array<T>>
23
+ | ReadonlySignal<Array<T>>
24
+ | (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);
25
+ fallback?: JSX.Element;
26
+ children: (value: T, index: number) => JSX.Element;
27
+ }
28
+
29
+ export function For<T>(props: ForProps<T>): JSX.Element | null {
30
+ const cache = useMemo(() => new Map(), []);
31
+ let list = (
32
+ (typeof props.each === "function" ? props.each() : props.each) as Signal<
33
+ Array<T>
34
+ >
35
+ ).value;
36
+
37
+ if (!list.length) return props.fallback || null;
38
+
39
+ const items = list.map((value, key) => {
40
+ if (!cache.has(value)) {
41
+ cache.set(value, props.children(value, key));
42
+ }
43
+ return cache.get(value);
44
+ });
45
+
46
+ return createElement(Fragment, null, items);
47
+ }
48
+
49
+ export function useLiveSignal<T>(
50
+ value: Signal<T> | ReadonlySignal<T>
51
+ ): Signal<Signal<T> | ReadonlySignal<T>> {
52
+ const s = useSignal(value);
53
+ if (s.peek() !== value) s.value = value;
54
+ return s;
55
+ }
56
+
57
+ export function useSignalRef<T>(value: T): Signal<T> & { current: T } {
58
+ const ref = useSignal(value) as Signal<T> & { current: T };
59
+ if (!("current" in ref))
60
+ Object.defineProperty(ref, "current", refSignalProto);
61
+ return ref;
62
+ }
63
+ const refSignalProto = {
64
+ configurable: true,
65
+ get(this: Signal) {
66
+ return this.value;
67
+ },
68
+ set(this: Signal, v: any) {
69
+ this.value = v;
70
+ },
71
+ };