diff --git a/.changeset/brave-numbers-develop.md b/.changeset/brave-numbers-develop.md new file mode 100644 index 000000000..9727a4d63 --- /dev/null +++ b/.changeset/brave-numbers-develop.md @@ -0,0 +1,5 @@ +--- +"@solid-primitives/keyed": minor +--- + +Add `Entries` control flow component. diff --git a/packages/keyed/README.md b/packages/keyed/README.md index 65a347620..23b911e49 100644 --- a/packages/keyed/README.md +++ b/packages/keyed/README.md @@ -13,6 +13,7 @@ Control Flow primitives and components that require specifying explicit keys to - [`keyArray`](#keyArray) - Reactively maps an array by specified key with a callback function - underlying helper for the `` control flow. - [`Key`](#Key) - Creates a list of elements by mapping items by provided key. +- [`Entries`](#Entries) - Creates a list of elements by mapping object entries. ## Installation @@ -118,6 +119,38 @@ Second argument of the map function is an index signal. https://codesandbox.io/s/solid-primitives-keyed-key-demo-gh7gd?file=/index.tsx +## `` + +Creates a list of elements by mapping object entries. Similar to Solid's `` and ``, but here, render function takes three arguments, and both value and index arguments are signals. + +### How to use it + +```tsx +import { Entries } from "@solid-primitives/keyed"; + +No items}> + {(key, value) => ( +
+ {key}: {value()} +
+ )} +
; +``` + +### Index argument + +Third argument of the map function is an index signal. + +```tsx +No items}> + {(key, value, index) => ( +
+ {key}: {value()} +
+ )} +
+``` + ## Changelog See [CHANGELOG.md](./CHANGELOG.md) diff --git a/packages/keyed/package.json b/packages/keyed/package.json index f70e479da..631197da1 100644 --- a/packages/keyed/package.json +++ b/packages/keyed/package.json @@ -14,7 +14,8 @@ "stage": 3, "list": [ "keyArray", - "Key" + "Key", + "Entries" ], "category": "Control Flow" }, diff --git a/packages/keyed/src/index.ts b/packages/keyed/src/index.ts index 933d5ebd2..8c65f2aeb 100644 --- a/packages/keyed/src/index.ts +++ b/packages/keyed/src/index.ts @@ -122,16 +122,55 @@ export function keyArray( * * @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyed#Key */ -export function Key(props: { +export function Key(props: { each?: readonly T[] | null | false; by: ((v: T) => any) | keyof T; - fallback?: U; - children: (v: Accessor, i: Accessor) => U; -}): Accessor { - const fallback = props.fallback ? () => props.fallback as U : undefined; + fallback?: JSX.Element; + children: (v: Accessor, i: Accessor) => JSX.Element; +}): Accessor { const { by } = props; - const key = typeof by === "function" ? by : (v: T) => v[by]; - const mapped = keyArray(() => props.each, key, props.children, { fallback }); + const mapped = keyArray( + () => props.each, + typeof by === "function" ? by : (v: T) => v[by], + props.children, + "fallback" in props ? { fallback: () => props.fallback } : undefined + ); + return createMemo(mapped); +} + +/** + * creates a list of elements from the entries of provided object + * + * @param props + * @param props.of object to iterate entries of (`Object.entries(object)`) + * @param props.children + * a map render function that receives an object key, **value signal** and **index signal** and returns a JSX-Element; if the list is empty, an optional fallback is returned: + * ```tsx + * No items}> + * {(key, value, index) =>
{key}: {value()}
} + *
+ * ``` + * + * @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyed#Entries + */ +export function Entries(props: { + of: T | undefined | null | false; + fallback?: JSX.Element; + children: (key: K, v: Accessor, i: Accessor) => JSX.Element; +}): Accessor { + const mapFn = props.children; + const mapped = keyArray( + () => props.of && (Object.entries(props.of) as [keyof T, T[keyof T]][]), + () => 0, + mapFn.length < 3 + ? keyvalue => + (mapFn as (key: keyof T, v: Accessor) => JSX.Element)( + keyvalue()[0], + () => keyvalue()[1] + ) + : (keyvalue, i) => mapFn(keyvalue()[0], () => keyvalue()[1], i), + "fallback" in props ? { fallback: () => props.fallback } : undefined + ); return createMemo(mapped); }