UNPKG

flexium

Version:

A lightweight, signals-based UI framework with cross-platform renderers

1 lines 6.96 kB
{"version":3,"sources":["../src/core/flow.ts"],"names":["For","props","each","children","renderItem","cache","list","newCache","vnodes","item","i","cached","indexSig","signal","vnode","Show","value","child","Match","Switch","when","matchChildren","content"],"mappings":"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","file":"chunk-S5WORXR2.mjs","sourcesContent":["import { VNode } from '../core/renderer';\nimport { StateGetter } from '../core/state';\nimport { signal, Signal } from './signal';\n\ninterface ForProps<T> {\n each: StateGetter<T[]>;\n children: ((item: T, index: () => number) => VNode)[];\n}\n\n/**\n * <For> component for efficient list rendering.\n * Reuses DOM nodes for items that haven't changed, avoiding full VDOM diffing.\n * \n * @example\n * <For each={items}>\n * {(item, index) => <div>{item.name}</div>}\n * </For>\n */\nexport function For<T>(props: ForProps<T>) {\n const { each, children } = props;\n const renderItem = children[0];\n \n // Cache VNodes and Index Signals by Item reference\n let cache = new Map<T, { vnode: VNode, indexSig: Signal<number> }>();\n\n return () => {\n const list = each() || [];\n const newCache = new Map<T, { vnode: VNode, indexSig: Signal<number> }>();\n \n const vnodes = list.map((item, i) => {\n let cached = cache.get(item);\n \n if (!cached) {\n // Create new index signal\n const indexSig = signal(i);\n \n // Create new VNode, passing index getter\n const vnode = renderItem(item, indexSig);\n \n // Ensure key is set\n if (vnode.key == null) {\n if (item != null && (item as any).id != null) {\n vnode.key = (item as any).id;\n } else if (typeof item === 'string' || typeof item === 'number') {\n vnode.key = item;\n }\n }\n \n cached = { vnode, indexSig };\n } else {\n // Update index if changed\n if (cached.indexSig.peek() !== i) {\n cached.indexSig.set(i);\n }\n }\n \n newCache.set(item, cached);\n return cached.vnode;\n });\n \n cache = newCache;\n return vnodes;\n };\n}\n\ninterface ShowProps<T> {\n when: StateGetter<T | undefined | null | false>;\n fallback?: VNode | (() => VNode);\n children: VNode[] | ((item: T) => VNode)[];\n}\n\n/**\n * <Show> component for conditional rendering.\n * Renders children when the condition is truthy, otherwise renders fallback.\n * \n * @example\n * <Show when={isLoggedIn} fallback={<div>Login</div>}>\n * <Dashboard />\n * </Show>\n * \n * // With callback to access truthy value\n * <Show when={user}>\n * {(u) => <div>Hello {u.name}</div>}\n * </Show>\n */\nexport function Show<T>(props: ShowProps<T>) {\n return () => {\n const value = props.when();\n if (value) {\n const child = props.children[0];\n return typeof child === 'function' && props.children.length === 1 \n ? (child as Function)(value) \n : child;\n }\n if (props.fallback) {\n return typeof props.fallback === 'function' ? (props.fallback as Function)() : props.fallback;\n }\n return null;\n };\n}\n\ninterface SwitchProps {\n fallback?: VNode;\n children: VNode[];\n}\n\ninterface MatchProps<T> {\n when: StateGetter<T | undefined | null | false>;\n children: VNode | ((item: T) => VNode);\n}\n\n/**\n * <Match> component to be used within <Switch>.\n * It does not render anything on its own.\n */\nexport function Match<T>(props: MatchProps<T>) {\n return props as any;\n}\n\n/**\n * <Switch> component for mutually exclusive conditional rendering.\n * Renders the first <Match> child whose `when` condition is truthy.\n * \n * @example\n * <Switch fallback={<div>Not Found</div>}>\n * <Match when={isLoading}>Loading...</Match>\n * <Match when={error}>Error: {error}</Match>\n * <Match when={data}>\n * {(d) => <DataView data={d} />}\n * </Match>\n * </Switch>\n */\nexport function Switch(props: SwitchProps) {\n return () => {\n const children = Array.isArray(props.children) ? props.children : [props.children];\n \n for (const child of children.flat()) {\n if (child && (child as any).type === Match) {\n const when = (child as any).props.when;\n // Check condition (track dependency)\n const value = typeof when === 'function' ? when() : when;\n \n if (value) {\n const matchChildren = (child as any).children;\n if (matchChildren && matchChildren.length > 0) {\n const content = matchChildren[0];\n return typeof content === 'function' ? content(value) : content;\n }\n return null;\n }\n }\n }\n return props.fallback || null;\n };\n}\n"]}