11import { PureContainerBase , PureContainerConfig } from "./PureContainer" ;
22import { isPromise } from "../util/isPromise" ;
33import { RenderingContext } from "./RenderingContext" ;
4- import { BooleanProp , StructuredProp , ResolveStructuredProp } from "./Prop" ;
4+ import { BooleanProp , StructuredProp , ResolveStructuredProp , Bind , Tpl , Expr , GetSet } from "./Prop" ;
5+ import { Selector } from "../data/Selector" ;
6+ import { AccessorChain } from "../data/createAccessorModelProxy" ;
57import { Instance } from "./Instance" ;
68
9+ /**
10+ * Helper type that extracts the value type from typed props (Selector, AccessorChain, GetSet).
11+ * Returns never for bindings (Bind, Tpl, Expr) since they don't carry type information.
12+ * This is used to properly resolve Prop<T> unions where we want to extract T.
13+ */
14+ type ExtractTypedPropValue < P > = P extends Selector < infer T >
15+ ? T
16+ : P extends AccessorChain < infer T >
17+ ? T
18+ : P extends GetSet < infer T >
19+ ? T
20+ : P extends Bind
21+ ? never
22+ : P extends Tpl
23+ ? never
24+ : P extends Expr
25+ ? never
26+ : P extends Record < string , any >
27+ ? never
28+ : P ;
29+
30+ /**
31+ * Utility type that resolves params which can be either a simple Prop<T> or a StructuredProp.
32+ * - For Prop<T> unions (including Selector, AccessorChain, GetSet, bindings), extracts T
33+ * - For plain bindings (Bind, Expr) used directly, resolves to any
34+ * - For structured props (objects), applies ResolveStructuredProp to resolve each property
35+ */
36+ type ResolveParams < P > = ExtractTypedPropValue < P > extends never
37+ ? P extends Bind
38+ ? any
39+ : P extends Tpl
40+ ? string
41+ : P extends Expr
42+ ? any
43+ : P extends Record < string , any >
44+ ? ResolveStructuredProp < P >
45+ : P
46+ : ExtractTypedPropValue < P > ;
47+
748/**
849 * Configuration for ContentResolver widget.
950 *
1051 * The params type parameter enables type inference for the onResolve callback:
1152 * - Literal values (numbers, strings, booleans) preserve their types
1253 * - AccessorChain<T> resolves to T
1354 * - Bind/Tpl/Expr resolve to any (type cannot be determined at compile time)
55+ * - Structured props (objects) have each property resolved individually
1456 *
1557 * @example
1658 * ```typescript
59+ * // Structured params (object)
1760 * <ContentResolver
1861 * params={{
1962 * count: 42, // number
@@ -23,18 +66,26 @@ import { Instance } from "./Instance";
2366 * // params.count is number, params.name is string
2467 * }}
2568 * />
69+ *
70+ * // Simple param (single value)
71+ * <ContentResolver
72+ * params={model.user.name} // AccessorChain<string>
73+ * onResolve={(name) => {
74+ * // name is string
75+ * }}
76+ * />
2677 * ```
2778 */
28- export interface ContentResolverConfig < P extends StructuredProp = StructuredProp > extends PureContainerConfig {
29- /** Parameters that trigger content resolution when changed. */
79+ export interface ContentResolverConfig < P = StructuredProp > extends PureContainerConfig {
80+ /** Parameters that trigger content resolution when changed. Can be a structured object or a single Prop. */
3081 params ?: P ;
3182
3283 /**
3384 * Callback function that resolves content based on params. Can return content directly or a Promise.
3485 * The params type is inferred from the params property - literal values and AccessorChain<T>
3586 * preserve their types, while bindings (bind/tpl/expr) resolve to `any`.
3687 */
37- onResolve ?: string | ( ( params : ResolveStructuredProp < P > , instance : Instance ) => any ) ;
88+ onResolve ?: string | ( ( params : ResolveParams < P > , instance : Instance ) => any ) ;
3889
3990 /** How to combine resolved content with initial content. Default is 'replace'. */
4091 mode ?: "replace" | "prepend" | "append" ;
@@ -43,15 +94,13 @@ export interface ContentResolverConfig<P extends StructuredProp = StructuredProp
4394 loading ?: BooleanProp ;
4495}
4596
46- export class ContentResolver < P extends StructuredProp = StructuredProp > extends PureContainerBase <
47- ContentResolverConfig < P >
48- > {
97+ export class ContentResolver < P = StructuredProp > extends PureContainerBase < ContentResolverConfig < P > > {
4998 constructor ( config ?: ContentResolverConfig < P > ) {
5099 super ( config ) ;
51100 }
52101
53102 declare mode : "replace" | "prepend" | "append" ;
54- declare onResolve ?: string | ( ( params : ResolveStructuredProp < P > , instance : Instance ) => any ) ;
103+ declare onResolve ?: string | ( ( params : ResolveParams < P > , instance : Instance ) => any ) ;
55104 declare initialItems : any ;
56105
57106 declareData ( ...args : any [ ] ) : void {
0 commit comments