@json-render/react-native 0.5.2 → 0.6.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// =============================================================================\n// Standard Component Definitions for React Native\n// =============================================================================\n\n/**\n * Standard component definitions for React Native catalogs.\n *\n * These can be used directly or extended with custom components.\n * All components are built using React Native core primitives only.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Layout Components\n // ==========================================================================\n\n Container: {\n props: z.object({\n padding: z.number().nullable(),\n paddingHorizontal: z.number().nullable(),\n paddingVertical: z.number().nullable(),\n margin: z.number().nullable(),\n backgroundColor: z.string().nullable(),\n borderRadius: z.number().nullable(),\n flex: z.number().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Generic container wrapper. Use for grouping elements with padding, margin, and background color.\",\n example: { padding: 16, backgroundColor: \"#FFFFFF\" },\n },\n\n Row: {\n props: z.object({\n gap: z.number().nullable(),\n alignItems: z\n .enum([\"flex-start\", \"center\", \"flex-end\", \"stretch\", \"baseline\"])\n .nullable(),\n justifyContent: z\n .enum([\n \"flex-start\",\n \"center\",\n \"flex-end\",\n \"space-between\",\n \"space-around\",\n \"space-evenly\",\n ])\n .nullable(),\n flexWrap: z.enum([\"wrap\", \"nowrap\"]).nullable(),\n padding: z.number().nullable(),\n flex: z.number().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Horizontal flex layout. Use for placing elements side by side.\",\n example: { gap: 12, alignItems: \"center\" },\n },\n\n Column: {\n props: z.object({\n gap: z.number().nullable(),\n alignItems: z\n .enum([\"flex-start\", \"center\", \"flex-end\", \"stretch\", \"baseline\"])\n .nullable(),\n justifyContent: z\n .enum([\n \"flex-start\",\n \"center\",\n \"flex-end\",\n \"space-between\",\n \"space-around\",\n \"space-evenly\",\n ])\n .nullable(),\n padding: z.number().nullable(),\n flex: z.number().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Vertical flex layout. Use for stacking elements top to bottom.\",\n example: { gap: 12, padding: 16 },\n },\n\n ScrollContainer: {\n props: z.object({\n horizontal: z.boolean().nullable(),\n showsScrollIndicator: z.boolean().nullable(),\n padding: z.number().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Scrollable container. Use for content that may overflow the screen.\",\n },\n\n SafeArea: {\n props: z.object({\n backgroundColor: z.string().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Safe area container that respects device notches and system bars. Use as the outermost wrapper for screens.\",\n },\n\n Spacer: {\n props: z.object({\n size: z.number().nullable(),\n flex: z.number().nullable(),\n }),\n slots: [],\n description:\n \"Empty space between elements. Set size for fixed spacing or flex for flexible spacing.\",\n },\n\n Pressable: {\n props: z.object({}),\n events: [\"press\", \"longPress\"],\n slots: [\"default\"],\n description:\n \"Touchable wrapper that triggers events on press. Wrap any element to make it tappable. Bind on.press to setState to update state for visibility-driven UIs like tabs.\",\n },\n\n Divider: {\n props: z.object({\n direction: z.enum([\"horizontal\", \"vertical\"]).nullable(),\n color: z.string().nullable(),\n thickness: z.number().nullable(),\n margin: z.number().nullable(),\n }),\n slots: [],\n description: \"Thin line separator between content sections.\",\n },\n\n // ==========================================================================\n // Content Components\n // ==========================================================================\n\n Heading: {\n props: z.object({\n text: z.string(),\n level: z.enum([\"h1\", \"h2\", \"h3\", \"h4\"]).nullable(),\n color: z.string().nullable(),\n align: z.enum([\"left\", \"center\", \"right\"]).nullable(),\n }),\n slots: [],\n description:\n \"Heading text at various levels. h1 is largest, h4 is smallest.\",\n example: { text: \"Welcome\", level: \"h1\" },\n },\n\n Paragraph: {\n props: z.object({\n text: z.string(),\n color: z.string().nullable(),\n align: z.enum([\"left\", \"center\", \"right\"]).nullable(),\n numberOfLines: z.number().nullable(),\n fontSize: z.number().nullable(),\n }),\n slots: [],\n description:\n \"Body text paragraph. Use for descriptions and longer content.\",\n example: { text: \"This is a paragraph of body text.\" },\n },\n\n Label: {\n props: z.object({\n text: z.string(),\n color: z.string().nullable(),\n bold: z.boolean().nullable(),\n size: z.enum([\"xs\", \"sm\", \"md\"]).nullable(),\n }),\n slots: [],\n description:\n \"Small utility text. Use for captions, form labels, and secondary information.\",\n example: { text: \"Status\", size: \"sm\" },\n },\n\n Image: {\n props: z.object({\n src: z.string(),\n alt: z.string().nullable(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n resizeMode: z.enum([\"cover\", \"contain\", \"stretch\", \"center\"]).nullable(),\n borderRadius: z.number().nullable(),\n }),\n slots: [],\n description: \"Image display. Provide a source URL and optional dimensions.\",\n example: {\n src: \"https://picsum.photos/300/200\",\n alt: \"Photo\",\n width: 300,\n height: 200,\n },\n },\n\n Avatar: {\n props: z.object({\n src: z.string().nullable(),\n initials: z.string().nullable(),\n size: z.enum([\"sm\", \"md\", \"lg\", \"xl\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n slots: [],\n description:\n \"Circular avatar showing an image or initials. Use for user profiles and contacts.\",\n example: { initials: \"JD\", size: \"md\" },\n },\n\n Badge: {\n props: z.object({\n label: z.string(),\n variant: z\n .enum([\"default\", \"info\", \"success\", \"warning\", \"error\"])\n .nullable(),\n }),\n slots: [],\n description:\n \"Small colored indicator with a label. Use for status, counts, and categories.\",\n example: { label: \"New\", variant: \"info\" },\n },\n\n Chip: {\n props: z.object({\n label: z.string(),\n selected: z.boolean().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n events: [\"press\", \"remove\"],\n slots: [],\n description:\n \"Tag or filter chip. Bind on.remove for removable chips, on.press for selectable chips.\",\n },\n\n // ==========================================================================\n // Input Components\n // ==========================================================================\n\n Button: {\n props: z.object({\n label: z.string(),\n variant: z\n .enum([\"primary\", \"secondary\", \"danger\", \"outline\", \"ghost\"])\n .nullable(),\n size: z.enum([\"sm\", \"md\", \"lg\"]).nullable(),\n disabled: z.boolean().nullable(),\n loading: z.boolean().nullable(),\n }),\n events: [\"press\"],\n slots: [],\n description:\n \"Pressable button with label. Set variant for styling. Bind on.press for the handler to call on press.\",\n example: { label: \"Submit\", variant: \"primary\" },\n },\n\n TextInput: {\n props: z.object({\n placeholder: z.string().nullable(),\n value: z.string().nullable(),\n secureTextEntry: z.boolean().nullable(),\n keyboardType: z\n .enum([\"default\", \"email-address\", \"numeric\", \"phone-pad\", \"url\"])\n .nullable(),\n multiline: z.boolean().nullable(),\n numberOfLines: z.number().nullable(),\n label: z.string().nullable(),\n flex: z.number().nullable(),\n }),\n events: [\"submit\", \"focus\", \"blur\"],\n slots: [],\n description:\n \"Text input field. Use $bindState to bind to the state model for two-way binding. The value typed by the user is stored at the bound path.\",\n example: {\n placeholder: \"Enter text...\",\n label: \"Name\",\n },\n },\n\n Switch: {\n props: z.object({\n checked: z.boolean().nullable(),\n label: z.string().nullable(),\n disabled: z.boolean().nullable(),\n }),\n events: [\"change\"],\n slots: [],\n description: \"Toggle switch. Use $bindState to bind to the state model.\",\n },\n\n Checkbox: {\n props: z.object({\n checked: z.boolean().nullable(),\n label: z.string().nullable(),\n disabled: z.boolean().nullable(),\n }),\n events: [\"change\"],\n slots: [],\n description:\n \"Checkbox for boolean selections. Use $bindState to bind to the state model.\",\n },\n\n Slider: {\n props: z.object({\n min: z.number().nullable(),\n max: z.number().nullable(),\n step: z.number().nullable(),\n value: z.number().nullable(),\n label: z.string().nullable(),\n color: z.string().nullable(),\n }),\n slots: [],\n description:\n \"Range slider for numeric values. Use $bindState to bind to the state model.\",\n },\n\n SearchBar: {\n props: z.object({\n placeholder: z.string().nullable(),\n value: z.string().nullable(),\n }),\n events: [\"submit\"],\n slots: [],\n description:\n \"Search input with icon. Bind on.submit to trigger search on submit.\",\n },\n\n // ==========================================================================\n // Feedback Components\n // ==========================================================================\n\n Spinner: {\n props: z.object({\n size: z.enum([\"small\", \"large\"]).nullable(),\n color: z.string().nullable(),\n }),\n slots: [],\n description: \"Loading spinner indicator. Use while content is loading.\",\n },\n\n ProgressBar: {\n props: z.object({\n progress: z.number(),\n color: z.string().nullable(),\n trackColor: z.string().nullable(),\n height: z.number().nullable(),\n }),\n slots: [],\n description: \"Horizontal progress bar. Set progress from 0 to 1.\",\n },\n\n // ==========================================================================\n // Composite Components\n // ==========================================================================\n\n Card: {\n props: z.object({\n title: z.string().nullable(),\n subtitle: z.string().nullable(),\n padding: z.number().nullable(),\n backgroundColor: z.string().nullable(),\n borderRadius: z.number().nullable(),\n elevated: z.boolean().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Elevated card container with optional title. Use for grouping related content.\",\n example: { title: \"Details\", padding: 16, elevated: true },\n },\n\n ListItem: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n leading: z.string().nullable(),\n trailing: z.string().nullable(),\n showChevron: z.boolean().nullable(),\n }),\n events: [\"press\"],\n slots: [],\n description:\n \"List row with title, subtitle, and optional leading/trailing text. Bind on.press for the press handler.\",\n example: {\n title: \"Settings\",\n subtitle: \"Manage your preferences\",\n showChevron: true,\n },\n },\n\n Modal: {\n props: z.object({\n visible: z.boolean(),\n title: z.string().nullable(),\n animationType: z.enum([\"slide\", \"fade\", \"none\"]).nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Modal overlay dialog. Use $bindState on visible to bind visibility to the state model.\",\n },\n};\n\n// =============================================================================\n// Standard Action Definitions for React Native\n// =============================================================================\n\n/**\n * Standard action definitions for React Native catalogs.\n *\n * These use React Native core APIs (Alert, Share, Linking) and\n * user-provided functions (navigate).\n */\nexport const standardActionDefinitions = {\n navigate: {\n params: z.object({\n screen: z.string(),\n params: z.record(z.string(), z.unknown()).nullable(),\n }),\n description:\n \"Navigate to a screen. Calls the user-provided navigation function.\",\n },\n\n goBack: {\n params: z.object({}),\n description: \"Navigate back to the previous screen.\",\n },\n\n showAlert: {\n params: z.object({\n title: z.string(),\n message: z.string().nullable(),\n buttons: z\n .array(\n z.object({\n text: z.string(),\n style: z.enum([\"default\", \"cancel\", \"destructive\"]).nullable(),\n action: z.string().nullable(),\n }),\n )\n .nullable(),\n }),\n description: \"Show a native alert dialog using Alert.alert().\",\n },\n\n share: {\n params: z.object({\n message: z.string(),\n url: z.string().nullable(),\n title: z.string().nullable(),\n }),\n description: \"Open the native share sheet using Share.share().\",\n },\n\n openURL: {\n params: z.object({\n url: z.string(),\n }),\n description: \"Open a URL in the default browser using Linking.openURL().\",\n },\n\n setState: {\n params: z.object({\n statePath: z.string(),\n value: z.unknown(),\n }),\n description: \"Update a value in the state model at the given statePath.\",\n },\n\n pushState: {\n params: z.object({\n statePath: z.string(),\n value: z.unknown(),\n clearStatePath: z.string().optional(),\n }),\n description:\n 'Append an item to an array in the state model. The value can contain { $state: \"/statePath\" } references to read from current state, and \"$id\" to auto-generate a unique ID. Use clearStatePath to reset another path after pushing (e.g. clear an input field). Example: { statePath: \"/todos\", value: { id: \"$id\", title: { $state: \"/newTodoText\" }, completed: false }, clearStatePath: \"/newTodoText\" }.',\n },\n\n removeState: {\n params: z.object({\n statePath: z.string(),\n index: z.number(),\n }),\n description:\n \"Remove an item from an array in the state model at the given index.\",\n },\n\n refresh: {\n params: z.object({\n target: z.string().nullable(),\n }),\n description:\n \"Trigger a data refresh. Optionally specify a target to refresh.\",\n },\n};\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Type for a component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n slots: string[];\n events?: string[];\n description: string;\n};\n\n/**\n * Type for an action definition\n */\nexport type ActionDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":[]}
@@ -50,27 +50,27 @@ var schema = defineSchema(
50
50
  // Element integrity
51
51
  "CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.",
52
52
  "SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.",
53
- 'When building repeating content backed by a state array (e.g. todos, posts, cart items), use the "repeat" field on a container element from the AVAILABLE COMPONENTS list. Example: { "type": "<ContainerComponent>", "props": { "gap": 8 }, "repeat": { "path": "/todos", "key": "id" }, "children": ["todo-item"] }. Inside repeated children, use "$item/field" for per-item state paths and "$index" for the current array index. Do NOT hardcode individual elements for each array item.',
53
+ 'When building repeating content backed by a state array (e.g. todos, posts, cart items), use the "repeat" field on a container element from the AVAILABLE COMPONENTS list. Example: { "type": "<ContainerComponent>", "props": { "gap": 8 }, "repeat": { "statePath": "/todos", "key": "id" }, "children": ["todo-item"] }. Inside repeated children, use { "$item": "field" } to read a field from the current item, and { "$index": true } for the current array index. For two-way binding to an item field use { "$bindItem": "completed" }. Do NOT hardcode individual elements for each array item.',
54
54
  // Visible field placement
55
- 'CRITICAL: The "visible" field goes on the ELEMENT object, NOT inside "props". Correct: {"type":"<ComponentName>","props":{},"visible":{"eq":[{"path":"/activeTab"},"home"]},"children":[...]}. WRONG: {"type":"<ComponentName>","props":{},"visible":{...},"children":[...]} with visible inside props.',
55
+ 'CRITICAL: The "visible" field goes on the ELEMENT object, NOT inside "props". Correct: {"type":"<ComponentName>","props":{},"visible":{"$state":"/activeTab","eq":"home"},"children":[...]}. WRONG: {"type":"<ComponentName>","props":{},"visible":{...},"children":[...]} with visible inside props.',
56
56
  // Tab navigation pattern
57
57
  "TAB NAVIGATION PATTERN: When building a UI with multiple tabs, use a pressable/tappable component + setState action + visible conditions to make tabs functional. ONLY use components from the AVAILABLE COMPONENTS list.",
58
- 'Each tab button should be a pressable component wrapping its icon/label children, with action "setState" and actionParams { "path": "/activeTab", "value": "tabName" }.',
59
- `Each tab's content section should have a visible condition: { "eq": [{ "path": "/activeTab" }, "tabName"] }.`,
58
+ 'Each tab button should be a pressable component wrapping its icon/label children, with action "setState" and actionParams { "statePath": "/activeTab", "value": "tabName" }.',
59
+ `Each tab's content section should have a visible condition: { "$state": "/activeTab", "eq": "tabName" }.`,
60
60
  "The first tab's content should NOT have a visible condition (so it shows by default when no tab is selected yet). All other tabs MUST have a visible condition.",
61
61
  // Tab active state highlighting (using dynamic props)
62
62
  "TAB ACTIVE STYLING: Use $cond dynamic props on icon elements inside each tab button so a single icon changes appearance based on the active tab.",
63
- ' - For the icon name: { "$cond": { "eq": [{ "path": "/activeTab" }, "thisTabName"] }, "$then": "home", "$else": "home-outline" }',
64
- ' - For the icon color: { "$cond": { "eq": [{ "path": "/activeTab" }, "thisTabName"] }, "$then": "#007AFF", "$else": "#8E8E93" }',
63
+ ' - For the icon name: { "$cond": { "$state": "/activeTab", "eq": "thisTabName" }, "$then": "home", "$else": "home-outline" }',
64
+ ' - For the icon color: { "$cond": { "$state": "/activeTab", "eq": "thisTabName" }, "$then": "#007AFF", "$else": "#8E8E93" }',
65
65
  " - For labels, use $cond on the color prop similarly.",
66
- ' - For the FIRST/DEFAULT tab, use { "$cond": { "or": [{ "eq": [{ "path": "/activeTab" }, "thisTabName"] }, { "not": { "path": "/activeTab" } }] }, "$then": "#007AFF", "$else": "#8E8E93" } so it appears active before any tab is tapped.',
66
+ ' - For the FIRST/DEFAULT tab, use { "$cond": [{ "$state": "/activeTab", "eq": "thisTabName" }], "$then": "#007AFF", "$else": "#8E8E93" } so it appears active before any tab is tapped. When no tab is selected yet, include a default tab with no visible condition.',
67
67
  // Push/pop screen navigation (all screens in one spec)
68
68
  'SCREEN NAVIGATION: Use a pressable component with action "push" and actionParams { "screen": "screenName" } to navigate to a new screen. Use action "pop" to go back. All screens must be defined in the SAME spec. ONLY use components from the AVAILABLE COMPONENTS list.',
69
- 'Each screen section uses a visible condition on /currentScreen: { "eq": [{ "path": "/currentScreen" }, "screenName"] }. The default/home screen should also be visible when /currentScreen is not set: { "or": [{ "eq": [{ "path": "/currentScreen" }, "home"] }, { "not": { "path": "/currentScreen" } }] }.',
69
+ 'Each screen section uses a visible condition on /currentScreen: { "$state": "/currentScreen", "eq": "screenName" }. The default/home screen should show by default (no visible condition) and all other screens should have the appropriate visible condition.',
70
70
  "push automatically maintains a /navStack in the state model so pop always returns to the previous screen.",
71
71
  'Include a back button on pushed screens using action "pop". Example: pressable(action:"pop") > row layout > back icon + back label. ONLY use components from the AVAILABLE COMPONENTS list.',
72
72
  "Use push/pop for drill-down flows: tapping a list item to see details, opening a profile, etc. Use setState + visible conditions for tab switching within a screen.",
73
- 'Example: A list screen with items that push to detail: a pressable component with action:"push" and actionParams:{screen:"detail"} wrapping each list item. The detail screen section has visible:{"eq":[{"path":"/currentScreen"},"detail"]} and contains a back button with action:"pop". ONLY use components from the AVAILABLE COMPONENTS list.'
73
+ 'Example: A list screen with items that push to detail: a pressable component with action:"push" and actionParams:{screen:"detail"} wrapping each list item. The detail screen section has visible:{"$state":"/currentScreen","eq":"detail"} and contains a back button with action:"pop". ONLY use components from the AVAILABLE COMPONENTS list.'
74
74
  ]
75
75
  }
76
76
  );
@@ -80,4 +80,4 @@ export {
80
80
  schema,
81
81
  elementTreeSchema
82
82
  };
83
- //# sourceMappingURL=chunk-MJPWQ6K7.mjs.map
83
+ //# sourceMappingURL=chunk-T27PQA6P.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema.ts"],"sourcesContent":["import { defineSchema } from \"@json-render/core\";\n\n/**\n * The schema for @json-render/react-native\n *\n * Defines:\n * - Spec: A flat tree of elements with keys, types, props, and children references\n * - Catalog: Components with props schemas, and optional actions\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like\n spec: s.object({\n /** Root element key */\n root: s.string(),\n /** Flat map of elements by key */\n elements: s.record(\n s.object({\n /** Component type from catalog */\n type: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Child element keys (flat reference) */\n children: s.array(s.string()),\n /** Visibility condition */\n visible: s.any(),\n }),\n ),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Component definitions */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Slots for this component. Use ['default'] for children, or named slots like ['header', 'footer'] */\n slots: s.array(s.string()),\n /** Description for AI generation hints */\n description: s.string(),\n /** Example prop values used in prompt examples (auto-generated from Zod schema if omitted) */\n example: s.any(),\n }),\n /** Action definitions (optional) */\n actions: s.map({\n /** Zod schema for action params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n defaultRules: [\n // Layout patterns\n \"FIXED BOTTOM BAR PATTERN: When building a screen with a fixed header and/or fixed bottom tab bar, the outermost vertical layout component must have flex:1 so it fills the screen. The scrollable content area must also have flex:1. Structure: screen wrapper > vertical layout(flex:1, gap:0) > [header, content wrapper(flex:1) > [scroll container(...)], bottom-tabs]. Both the outer layout AND the content wrapper need flex:1. ONLY use components from the AVAILABLE COMPONENTS list.\",\n \"NEVER place a bottom tab bar or fixed footer inside a scroll container. It must be a sibling AFTER the flex:1 container that holds the scroll content.\",\n\n // Element integrity\n \"CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.\",\n \"SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.\",\n 'When building repeating content backed by a state array (e.g. todos, posts, cart items), use the \"repeat\" field on a container element from the AVAILABLE COMPONENTS list. Example: { \"type\": \"<ContainerComponent>\", \"props\": { \"gap\": 8 }, \"repeat\": { \"statePath\": \"/todos\", \"key\": \"id\" }, \"children\": [\"todo-item\"] }. Inside repeated children, use { \"$item\": \"field\" } to read a field from the current item, and { \"$index\": true } for the current array index. For two-way binding to an item field use { \"$bindItem\": \"completed\" }. Do NOT hardcode individual elements for each array item.',\n\n // Visible field placement\n 'CRITICAL: The \"visible\" field goes on the ELEMENT object, NOT inside \"props\". Correct: {\"type\":\"<ComponentName>\",\"props\":{},\"visible\":{\"$state\":\"/activeTab\",\"eq\":\"home\"},\"children\":[...]}. WRONG: {\"type\":\"<ComponentName>\",\"props\":{},\"visible\":{...},\"children\":[...]} with visible inside props.',\n\n // Tab navigation pattern\n \"TAB NAVIGATION PATTERN: When building a UI with multiple tabs, use a pressable/tappable component + setState action + visible conditions to make tabs functional. ONLY use components from the AVAILABLE COMPONENTS list.\",\n 'Each tab button should be a pressable component wrapping its icon/label children, with action \"setState\" and actionParams { \"statePath\": \"/activeTab\", \"value\": \"tabName\" }.',\n 'Each tab\\'s content section should have a visible condition: { \"$state\": \"/activeTab\", \"eq\": \"tabName\" }.',\n \"The first tab's content should NOT have a visible condition (so it shows by default when no tab is selected yet). All other tabs MUST have a visible condition.\",\n\n // Tab active state highlighting (using dynamic props)\n \"TAB ACTIVE STYLING: Use $cond dynamic props on icon elements inside each tab button so a single icon changes appearance based on the active tab.\",\n ' - For the icon name: { \"$cond\": { \"$state\": \"/activeTab\", \"eq\": \"thisTabName\" }, \"$then\": \"home\", \"$else\": \"home-outline\" }',\n ' - For the icon color: { \"$cond\": { \"$state\": \"/activeTab\", \"eq\": \"thisTabName\" }, \"$then\": \"#007AFF\", \"$else\": \"#8E8E93\" }',\n \" - For labels, use $cond on the color prop similarly.\",\n ' - For the FIRST/DEFAULT tab, use { \"$cond\": [{ \"$state\": \"/activeTab\", \"eq\": \"thisTabName\" }], \"$then\": \"#007AFF\", \"$else\": \"#8E8E93\" } so it appears active before any tab is tapped. When no tab is selected yet, include a default tab with no visible condition.',\n\n // Push/pop screen navigation (all screens in one spec)\n 'SCREEN NAVIGATION: Use a pressable component with action \"push\" and actionParams { \"screen\": \"screenName\" } to navigate to a new screen. Use action \"pop\" to go back. All screens must be defined in the SAME spec. ONLY use components from the AVAILABLE COMPONENTS list.',\n 'Each screen section uses a visible condition on /currentScreen: { \"$state\": \"/currentScreen\", \"eq\": \"screenName\" }. The default/home screen should show by default (no visible condition) and all other screens should have the appropriate visible condition.',\n \"push automatically maintains a /navStack in the state model so pop always returns to the previous screen.\",\n 'Include a back button on pushed screens using action \"pop\". Example: pressable(action:\"pop\") > row layout > back icon + back label. ONLY use components from the AVAILABLE COMPONENTS list.',\n \"Use push/pop for drill-down flows: tapping a list item to see details, opening a profile, etc. Use setState + visible conditions for tab switching within a screen.\",\n 'Example: A list screen with items that push to detail: a pressable component with action:\"push\" and actionParams:{screen:\"detail\"} wrapping each list item. The detail screen section has visible:{\"$state\":\"/currentScreen\",\"eq\":\"detail\"} and contains a back button with action:\"pop\". ONLY use components from the AVAILABLE COMPONENTS list.',\n ],\n },\n);\n\n/**\n * Type for the React Native schema\n */\nexport type ReactNativeSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type ReactNativeSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n\n// Backward compatibility aliases\n/** @deprecated Use `schema` instead */\nexport const elementTreeSchema = schema;\n/** @deprecated Use `ReactNativeSchema` instead */\nexport type ElementTreeSchema = ReactNativeSchema;\n/** @deprecated Use `ReactNativeSpec` instead */\nexport type ElementTreeSpec<T> = ReactNativeSpec<T>;\n"],"mappings":";AAAA,SAAS,oBAAoB;AAStB,IAAM,SAAS;AAAA,EACpB,CAAC,OAAO;AAAA;AAAA,IAEN,MAAM,EAAE,OAAO;AAAA;AAAA,MAEb,MAAM,EAAE,OAAO;AAAA;AAAA,MAEf,UAAU,EAAE;AAAA,QACV,EAAE,OAAO;AAAA;AAAA,UAEP,MAAM,EAAE,IAAI,oBAAoB;AAAA;AAAA,UAEhC,OAAO,EAAE,QAAQ,oBAAoB;AAAA;AAAA,UAErC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA;AAAA,UAE5B,SAAS,EAAE,IAAI;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA;AAAA,IAGD,SAAS,EAAE,OAAO;AAAA;AAAA,MAEhB,YAAY,EAAE,IAAI;AAAA;AAAA,QAEhB,OAAO,EAAE,IAAI;AAAA;AAAA,QAEb,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA;AAAA,QAEzB,aAAa,EAAE,OAAO;AAAA;AAAA,QAEtB,SAAS,EAAE,IAAI;AAAA,MACjB,CAAC;AAAA;AAAA,MAED,SAAS,EAAE,IAAI;AAAA;AAAA,QAEb,QAAQ,EAAE,IAAI;AAAA;AAAA,QAEd,aAAa,EAAE,OAAO;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,cAAc;AAAA;AAAA,MAEZ;AAAA,MACA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAkBO,IAAM,oBAAoB;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, ComponentType } from 'react';
3
- import { StateModel as StateModel$1, AuthState, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, LegacyCatalog, ComponentDefinition, FlatElement } from '@json-render/core';
4
- export { Spec } from '@json-render/core';
3
+ import { StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, FlatElement } from '@json-render/core';
4
+ export { Spec, StateModel } from '@json-render/core';
5
5
  export { ElementTreeSchema, ElementTreeSpec, ReactNativeSchema, ReactNativeSpec, elementTreeSchema, schema } from './schema.mjs';
6
6
  export { ActionDefinition, ComponentDefinition, standardActionDefinitions, standardComponentDefinitions } from './catalog.mjs';
7
7
  import 'zod';
@@ -11,9 +11,7 @@ import 'zod';
11
11
  */
12
12
  interface StateContextValue {
13
13
  /** The current state model */
14
- state: StateModel$1;
15
- /** Auth state for visibility evaluation */
16
- authState?: AuthState;
14
+ state: StateModel;
17
15
  /** Get a value by path */
18
16
  get: (path: string) => unknown;
19
17
  /** Set a value by path */
@@ -26,9 +24,7 @@ interface StateContextValue {
26
24
  */
27
25
  interface StateProviderProps {
28
26
  /** Initial state model */
29
- initialState?: StateModel$1;
30
- /** Auth state */
31
- authState?: AuthState;
27
+ initialState?: StateModel;
32
28
  /** Callback when state changes */
33
29
  onStateChange?: (path: string, value: unknown) => void;
34
30
  children: ReactNode;
@@ -36,7 +32,7 @@ interface StateProviderProps {
36
32
  /**
37
33
  * Provider for state model context
38
34
  */
39
- declare function StateProvider({ initialState, authState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
35
+ declare function StateProvider({ initialState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
40
36
  /**
41
37
  * Hook to access the state context
42
38
  */
@@ -46,7 +42,12 @@ declare function useStateStore(): StateContextValue;
46
42
  */
47
43
  declare function useStateValue<T>(path: string): T | undefined;
48
44
  /**
49
- * Hook to get and set a value from the state model (like useState)
45
+ * Hook to get and set a value from the state model (like useState).
46
+ *
47
+ * @deprecated Use {@link useBoundProp} with `$bindState` expressions instead.
48
+ * `useStateBinding` takes a raw state path string, while `useBoundProp` works
49
+ * with the renderer's `bindings` map and supports both `$bindState` and
50
+ * `$bindItem` expressions.
50
51
  */
51
52
  declare function useStateBinding<T>(path: string): [T | undefined, (value: T) => void];
52
53
 
@@ -210,60 +211,55 @@ declare function useFieldValidation(path: string, config?: ValidationConfig): {
210
211
  };
211
212
 
212
213
  /**
213
- * Repeat scope value provided to child elements inside a Repeat.
214
+ * Repeat scope value provided to child elements inside a repeated element.
214
215
  */
215
216
  interface RepeatScopeValue {
216
- /** Absolute state path to the current array item (e.g. "/todos/0") */
217
- basePath: string;
217
+ /** The current array item object */
218
+ item: unknown;
218
219
  /** Index of the current item in the array */
219
220
  index: number;
221
+ /** Absolute state path to the current array item (e.g. "/todos/0") — used for statePath two-way binding */
222
+ basePath: string;
220
223
  }
221
224
  /**
222
- * Provides repeat scope to child elements so $item and $index tokens resolve correctly.
225
+ * Provides repeat scope to child elements so $item and $index expressions resolve correctly.
223
226
  */
224
- declare function RepeatScopeProvider({ basePath, index, children, }: RepeatScopeValue & {
227
+ declare function RepeatScopeProvider({ item, index, basePath, children, }: RepeatScopeValue & {
225
228
  children: ReactNode;
226
229
  }): react_jsx_runtime.JSX.Element;
227
230
  /**
228
- * Read the current repeat scope (or null if not inside a Repeat).
231
+ * Read the current repeat scope (or null if not inside a repeated element).
229
232
  */
230
233
  declare function useRepeatScope(): RepeatScopeValue | null;
231
- /**
232
- * Recursively rewrite `$item` and `$index` tokens in a value.
233
- *
234
- * - `"$item/foo"` → `"{basePath}/foo"`
235
- * - `"$item"` → `"{basePath}"`
236
- * - `"$index"` → `index` (number)
237
- */
238
- declare function rewriteRepeatTokens(value: unknown, basePath: string, index: number): unknown;
239
234
 
240
235
  /**
241
236
  * State setter function for updating application state
242
237
  */
243
238
  type SetState = (updater: (prev: Record<string, unknown>) => Record<string, unknown>) => void;
244
- /**
245
- * State model type (generic record)
246
- */
247
- type StateModel = Record<string, unknown>;
248
239
  /**
249
240
  * Context passed to component render functions
250
241
  * @example
251
242
  * const Button: ComponentFn<typeof catalog, 'Button'> = (ctx) => {
252
- * return <Pressable onPress={() => ctx.emit?.("press")}><Text>{ctx.props.label}</Text></Pressable>
243
+ * return <Pressable onPress={() => ctx.emit("press")}><Text>{ctx.props.label}</Text></Pressable>
253
244
  * }
254
245
  */
255
246
  interface ComponentContext<C extends Catalog, K extends keyof InferCatalogComponents<C>> {
256
247
  props: InferComponentProps<C, K>;
257
248
  children?: ReactNode;
258
249
  /** Emit a named event. The renderer resolves the event to an action binding from the element's `on` field. */
259
- emit?: (event: string) => void;
250
+ emit: (event: string) => void;
251
+ /**
252
+ * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions.
253
+ * Maps prop name → absolute state path for write-back.
254
+ */
255
+ bindings?: Record<string, string>;
260
256
  loading?: boolean;
261
257
  }
262
258
  /**
263
259
  * Component render function type for React Native
264
260
  * @example
265
261
  * const Button: ComponentFn<typeof catalog, 'Button'> = ({ props, emit }) => (
266
- * <Pressable onPress={() => emit?.("press")}><Text>{props.label}</Text></Pressable>
262
+ * <Pressable onPress={() => emit("press")}><Text>{props.label}</Text></Pressable>
267
263
  * );
268
264
  */
269
265
  type ComponentFn<C extends Catalog, K extends keyof InferCatalogComponents<C>> = (ctx: ComponentContext<C, K>) => ReactNode;
@@ -329,8 +325,14 @@ interface ComponentRenderProps<P = Record<string, unknown>> {
329
325
  element: UIElement<string, P>;
330
326
  /** Rendered children */
331
327
  children?: ReactNode;
332
- /** Emit a named event. The renderer resolves the event to action binding(s) from the element's `on` field. */
333
- emit?: (event: string) => void;
328
+ /** Emit a named event. The renderer resolves the event to action binding(s) from the element's `on` field. Always provided by the renderer. */
329
+ emit: (event: string) => void;
330
+ /**
331
+ * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions.
332
+ * Maps prop name → absolute state path for write-back.
333
+ * Only present when at least one prop uses `{ $bindState: "..." }` or `{ $bindItem: "..." }`.
334
+ */
335
+ bindings?: Record<string, string>;
334
336
  /** Whether the parent is loading */
335
337
  loading?: boolean;
336
338
  }
@@ -391,13 +393,8 @@ interface JSONUIProviderProps {
391
393
  registry?: ComponentRegistry;
392
394
  /** Initial state model */
393
395
  initialState?: Record<string, unknown>;
394
- /** Auth state */
395
- authState?: {
396
- isSignedIn: boolean;
397
- user?: Record<string, unknown>;
398
- };
399
396
  /** Action handlers */
400
- actionHandlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
397
+ handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
401
398
  /** Navigation function */
402
399
  navigate?: (path: string) => void;
403
400
  /** Custom validation functions */
@@ -409,12 +406,7 @@ interface JSONUIProviderProps {
409
406
  /**
410
407
  * Combined provider for all JSONUI contexts
411
408
  */
412
- declare function JSONUIProvider({ registry, initialState, authState, actionHandlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
413
- /**
414
- * Legacy helper to create a renderer component from a catalog
415
- * @deprecated Use createRenderer with the new catalog API instead
416
- */
417
- declare function createRendererFromCatalog<C extends LegacyCatalog<Record<string, ComponentDefinition>>>(_catalog: C, registry: ComponentRegistry): ComponentType<Omit<RendererProps, "registry">>;
409
+ declare function JSONUIProvider({ registry, initialState, handlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
418
410
  /**
419
411
  * Result returned by defineRegistry
420
412
  */
@@ -479,11 +471,6 @@ interface CreateRendererProps {
479
471
  onStateChange?: (path: string, value: unknown) => void;
480
472
  /** Whether the spec is currently loading/streaming */
481
473
  loading?: boolean;
482
- /** Auth state for visibility conditions */
483
- authState?: {
484
- isSignedIn: boolean;
485
- user?: Record<string, unknown>;
486
- };
487
474
  /** Fallback component for unknown types */
488
475
  fallback?: ComponentRenderer;
489
476
  }
@@ -517,6 +504,18 @@ declare function createRenderer<TDef extends SchemaDefinition, TCatalog extends
517
504
  }>;
518
505
  }>(catalog: Catalog<TDef, TCatalog>, components: ComponentMap<TCatalog["components"]>): ComponentType<CreateRendererProps>;
519
506
 
507
+ /**
508
+ * Hook for two-way bound props. Returns `[value, setValue]` where:
509
+ *
510
+ * - `value` is the already-resolved prop value (passed through from render props)
511
+ * - `setValue` writes back to the bound state path (no-op if not bound)
512
+ *
513
+ * @example
514
+ * ```tsx
515
+ * const [value, setValue] = useBoundProp<string>(element.props.value, bindings?.value);
516
+ * ```
517
+ */
518
+ declare function useBoundProp<T>(propValue: T | undefined, bindingPath: string | undefined): [T | undefined, (value: T) => void];
520
519
  /**
521
520
  * Options for useUIStream
522
521
  */
@@ -588,4 +587,4 @@ declare function useUIStream({ api, onComplete, onError, fetch: fetchFn, validat
588
587
  */
589
588
  declare function flatToTree(elements: FlatElement[]): Spec;
590
589
 
591
- export { type ActionContextValue, type ActionFn, ActionProvider, type ActionProviderProps, type Actions, type ComponentContext, type ComponentFn, type ComponentMap, type ComponentRegistry, type ComponentRenderProps, type ComponentRenderer, type Components, ConfirmDialog, type ConfirmDialogProps, type CreateRendererProps, type DefineRegistryResult, type FieldValidationState, JSONUIProvider, type JSONUIProviderProps, type PendingConfirmation, Renderer, type RendererProps, RepeatScopeProvider, type RepeatScopeValue, type SetState, type StateContextValue, type StateModel, StateProvider, type StateProviderProps, type UseUIStreamOptions, type UseUIStreamReturn, type ValidationContextValue, ValidationProvider, type ValidationProviderProps, type VisibilityContextValue, VisibilityProvider, type VisibilityProviderProps, createRenderer, createRendererFromCatalog, createStandardActionHandlers, defineRegistry, flatToTree, rewriteRepeatTokens, standardComponents, useAction, useActions, useFieldValidation, useIsVisible, useRepeatScope, useStateBinding, useStateStore, useStateValue, useUIStream, useValidation, useVisibility };
590
+ export { type ActionContextValue, type ActionFn, ActionProvider, type ActionProviderProps, type Actions, type ComponentContext, type ComponentFn, type ComponentMap, type ComponentRegistry, type ComponentRenderProps, type ComponentRenderer, type Components, ConfirmDialog, type ConfirmDialogProps, type CreateRendererProps, type DefineRegistryResult, type FieldValidationState, JSONUIProvider, type JSONUIProviderProps, type PendingConfirmation, Renderer, type RendererProps, RepeatScopeProvider, type RepeatScopeValue, type SetState, type StateContextValue, StateProvider, type StateProviderProps, type UseUIStreamOptions, type UseUIStreamReturn, type ValidationContextValue, ValidationProvider, type ValidationProviderProps, type VisibilityContextValue, VisibilityProvider, type VisibilityProviderProps, createRenderer, createStandardActionHandlers, defineRegistry, flatToTree, standardComponents, useAction, useActions, useBoundProp, useFieldValidation, useIsVisible, useRepeatScope, useStateBinding, useStateStore, useStateValue, useUIStream, useValidation, useVisibility };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, ComponentType } from 'react';
3
- import { StateModel as StateModel$1, AuthState, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, LegacyCatalog, ComponentDefinition, FlatElement } from '@json-render/core';
4
- export { Spec } from '@json-render/core';
3
+ import { StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, FlatElement } from '@json-render/core';
4
+ export { Spec, StateModel } from '@json-render/core';
5
5
  export { ElementTreeSchema, ElementTreeSpec, ReactNativeSchema, ReactNativeSpec, elementTreeSchema, schema } from './schema.js';
6
6
  export { ActionDefinition, ComponentDefinition, standardActionDefinitions, standardComponentDefinitions } from './catalog.js';
7
7
  import 'zod';
@@ -11,9 +11,7 @@ import 'zod';
11
11
  */
12
12
  interface StateContextValue {
13
13
  /** The current state model */
14
- state: StateModel$1;
15
- /** Auth state for visibility evaluation */
16
- authState?: AuthState;
14
+ state: StateModel;
17
15
  /** Get a value by path */
18
16
  get: (path: string) => unknown;
19
17
  /** Set a value by path */
@@ -26,9 +24,7 @@ interface StateContextValue {
26
24
  */
27
25
  interface StateProviderProps {
28
26
  /** Initial state model */
29
- initialState?: StateModel$1;
30
- /** Auth state */
31
- authState?: AuthState;
27
+ initialState?: StateModel;
32
28
  /** Callback when state changes */
33
29
  onStateChange?: (path: string, value: unknown) => void;
34
30
  children: ReactNode;
@@ -36,7 +32,7 @@ interface StateProviderProps {
36
32
  /**
37
33
  * Provider for state model context
38
34
  */
39
- declare function StateProvider({ initialState, authState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
35
+ declare function StateProvider({ initialState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
40
36
  /**
41
37
  * Hook to access the state context
42
38
  */
@@ -46,7 +42,12 @@ declare function useStateStore(): StateContextValue;
46
42
  */
47
43
  declare function useStateValue<T>(path: string): T | undefined;
48
44
  /**
49
- * Hook to get and set a value from the state model (like useState)
45
+ * Hook to get and set a value from the state model (like useState).
46
+ *
47
+ * @deprecated Use {@link useBoundProp} with `$bindState` expressions instead.
48
+ * `useStateBinding` takes a raw state path string, while `useBoundProp` works
49
+ * with the renderer's `bindings` map and supports both `$bindState` and
50
+ * `$bindItem` expressions.
50
51
  */
51
52
  declare function useStateBinding<T>(path: string): [T | undefined, (value: T) => void];
52
53
 
@@ -210,60 +211,55 @@ declare function useFieldValidation(path: string, config?: ValidationConfig): {
210
211
  };
211
212
 
212
213
  /**
213
- * Repeat scope value provided to child elements inside a Repeat.
214
+ * Repeat scope value provided to child elements inside a repeated element.
214
215
  */
215
216
  interface RepeatScopeValue {
216
- /** Absolute state path to the current array item (e.g. "/todos/0") */
217
- basePath: string;
217
+ /** The current array item object */
218
+ item: unknown;
218
219
  /** Index of the current item in the array */
219
220
  index: number;
221
+ /** Absolute state path to the current array item (e.g. "/todos/0") — used for statePath two-way binding */
222
+ basePath: string;
220
223
  }
221
224
  /**
222
- * Provides repeat scope to child elements so $item and $index tokens resolve correctly.
225
+ * Provides repeat scope to child elements so $item and $index expressions resolve correctly.
223
226
  */
224
- declare function RepeatScopeProvider({ basePath, index, children, }: RepeatScopeValue & {
227
+ declare function RepeatScopeProvider({ item, index, basePath, children, }: RepeatScopeValue & {
225
228
  children: ReactNode;
226
229
  }): react_jsx_runtime.JSX.Element;
227
230
  /**
228
- * Read the current repeat scope (or null if not inside a Repeat).
231
+ * Read the current repeat scope (or null if not inside a repeated element).
229
232
  */
230
233
  declare function useRepeatScope(): RepeatScopeValue | null;
231
- /**
232
- * Recursively rewrite `$item` and `$index` tokens in a value.
233
- *
234
- * - `"$item/foo"` → `"{basePath}/foo"`
235
- * - `"$item"` → `"{basePath}"`
236
- * - `"$index"` → `index` (number)
237
- */
238
- declare function rewriteRepeatTokens(value: unknown, basePath: string, index: number): unknown;
239
234
 
240
235
  /**
241
236
  * State setter function for updating application state
242
237
  */
243
238
  type SetState = (updater: (prev: Record<string, unknown>) => Record<string, unknown>) => void;
244
- /**
245
- * State model type (generic record)
246
- */
247
- type StateModel = Record<string, unknown>;
248
239
  /**
249
240
  * Context passed to component render functions
250
241
  * @example
251
242
  * const Button: ComponentFn<typeof catalog, 'Button'> = (ctx) => {
252
- * return <Pressable onPress={() => ctx.emit?.("press")}><Text>{ctx.props.label}</Text></Pressable>
243
+ * return <Pressable onPress={() => ctx.emit("press")}><Text>{ctx.props.label}</Text></Pressable>
253
244
  * }
254
245
  */
255
246
  interface ComponentContext<C extends Catalog, K extends keyof InferCatalogComponents<C>> {
256
247
  props: InferComponentProps<C, K>;
257
248
  children?: ReactNode;
258
249
  /** Emit a named event. The renderer resolves the event to an action binding from the element's `on` field. */
259
- emit?: (event: string) => void;
250
+ emit: (event: string) => void;
251
+ /**
252
+ * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions.
253
+ * Maps prop name → absolute state path for write-back.
254
+ */
255
+ bindings?: Record<string, string>;
260
256
  loading?: boolean;
261
257
  }
262
258
  /**
263
259
  * Component render function type for React Native
264
260
  * @example
265
261
  * const Button: ComponentFn<typeof catalog, 'Button'> = ({ props, emit }) => (
266
- * <Pressable onPress={() => emit?.("press")}><Text>{props.label}</Text></Pressable>
262
+ * <Pressable onPress={() => emit("press")}><Text>{props.label}</Text></Pressable>
267
263
  * );
268
264
  */
269
265
  type ComponentFn<C extends Catalog, K extends keyof InferCatalogComponents<C>> = (ctx: ComponentContext<C, K>) => ReactNode;
@@ -329,8 +325,14 @@ interface ComponentRenderProps<P = Record<string, unknown>> {
329
325
  element: UIElement<string, P>;
330
326
  /** Rendered children */
331
327
  children?: ReactNode;
332
- /** Emit a named event. The renderer resolves the event to action binding(s) from the element's `on` field. */
333
- emit?: (event: string) => void;
328
+ /** Emit a named event. The renderer resolves the event to action binding(s) from the element's `on` field. Always provided by the renderer. */
329
+ emit: (event: string) => void;
330
+ /**
331
+ * Two-way binding paths resolved from `$bindState` / `$bindItem` expressions.
332
+ * Maps prop name → absolute state path for write-back.
333
+ * Only present when at least one prop uses `{ $bindState: "..." }` or `{ $bindItem: "..." }`.
334
+ */
335
+ bindings?: Record<string, string>;
334
336
  /** Whether the parent is loading */
335
337
  loading?: boolean;
336
338
  }
@@ -391,13 +393,8 @@ interface JSONUIProviderProps {
391
393
  registry?: ComponentRegistry;
392
394
  /** Initial state model */
393
395
  initialState?: Record<string, unknown>;
394
- /** Auth state */
395
- authState?: {
396
- isSignedIn: boolean;
397
- user?: Record<string, unknown>;
398
- };
399
396
  /** Action handlers */
400
- actionHandlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
397
+ handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
401
398
  /** Navigation function */
402
399
  navigate?: (path: string) => void;
403
400
  /** Custom validation functions */
@@ -409,12 +406,7 @@ interface JSONUIProviderProps {
409
406
  /**
410
407
  * Combined provider for all JSONUI contexts
411
408
  */
412
- declare function JSONUIProvider({ registry, initialState, authState, actionHandlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
413
- /**
414
- * Legacy helper to create a renderer component from a catalog
415
- * @deprecated Use createRenderer with the new catalog API instead
416
- */
417
- declare function createRendererFromCatalog<C extends LegacyCatalog<Record<string, ComponentDefinition>>>(_catalog: C, registry: ComponentRegistry): ComponentType<Omit<RendererProps, "registry">>;
409
+ declare function JSONUIProvider({ registry, initialState, handlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
418
410
  /**
419
411
  * Result returned by defineRegistry
420
412
  */
@@ -479,11 +471,6 @@ interface CreateRendererProps {
479
471
  onStateChange?: (path: string, value: unknown) => void;
480
472
  /** Whether the spec is currently loading/streaming */
481
473
  loading?: boolean;
482
- /** Auth state for visibility conditions */
483
- authState?: {
484
- isSignedIn: boolean;
485
- user?: Record<string, unknown>;
486
- };
487
474
  /** Fallback component for unknown types */
488
475
  fallback?: ComponentRenderer;
489
476
  }
@@ -517,6 +504,18 @@ declare function createRenderer<TDef extends SchemaDefinition, TCatalog extends
517
504
  }>;
518
505
  }>(catalog: Catalog<TDef, TCatalog>, components: ComponentMap<TCatalog["components"]>): ComponentType<CreateRendererProps>;
519
506
 
507
+ /**
508
+ * Hook for two-way bound props. Returns `[value, setValue]` where:
509
+ *
510
+ * - `value` is the already-resolved prop value (passed through from render props)
511
+ * - `setValue` writes back to the bound state path (no-op if not bound)
512
+ *
513
+ * @example
514
+ * ```tsx
515
+ * const [value, setValue] = useBoundProp<string>(element.props.value, bindings?.value);
516
+ * ```
517
+ */
518
+ declare function useBoundProp<T>(propValue: T | undefined, bindingPath: string | undefined): [T | undefined, (value: T) => void];
520
519
  /**
521
520
  * Options for useUIStream
522
521
  */
@@ -588,4 +587,4 @@ declare function useUIStream({ api, onComplete, onError, fetch: fetchFn, validat
588
587
  */
589
588
  declare function flatToTree(elements: FlatElement[]): Spec;
590
589
 
591
- export { type ActionContextValue, type ActionFn, ActionProvider, type ActionProviderProps, type Actions, type ComponentContext, type ComponentFn, type ComponentMap, type ComponentRegistry, type ComponentRenderProps, type ComponentRenderer, type Components, ConfirmDialog, type ConfirmDialogProps, type CreateRendererProps, type DefineRegistryResult, type FieldValidationState, JSONUIProvider, type JSONUIProviderProps, type PendingConfirmation, Renderer, type RendererProps, RepeatScopeProvider, type RepeatScopeValue, type SetState, type StateContextValue, type StateModel, StateProvider, type StateProviderProps, type UseUIStreamOptions, type UseUIStreamReturn, type ValidationContextValue, ValidationProvider, type ValidationProviderProps, type VisibilityContextValue, VisibilityProvider, type VisibilityProviderProps, createRenderer, createRendererFromCatalog, createStandardActionHandlers, defineRegistry, flatToTree, rewriteRepeatTokens, standardComponents, useAction, useActions, useFieldValidation, useIsVisible, useRepeatScope, useStateBinding, useStateStore, useStateValue, useUIStream, useValidation, useVisibility };
590
+ export { type ActionContextValue, type ActionFn, ActionProvider, type ActionProviderProps, type Actions, type ComponentContext, type ComponentFn, type ComponentMap, type ComponentRegistry, type ComponentRenderProps, type ComponentRenderer, type Components, ConfirmDialog, type ConfirmDialogProps, type CreateRendererProps, type DefineRegistryResult, type FieldValidationState, JSONUIProvider, type JSONUIProviderProps, type PendingConfirmation, Renderer, type RendererProps, RepeatScopeProvider, type RepeatScopeValue, type SetState, type StateContextValue, StateProvider, type StateProviderProps, type UseUIStreamOptions, type UseUIStreamReturn, type ValidationContextValue, ValidationProvider, type ValidationProviderProps, type VisibilityContextValue, VisibilityProvider, type VisibilityProviderProps, createRenderer, createStandardActionHandlers, defineRegistry, flatToTree, standardComponents, useAction, useActions, useBoundProp, useFieldValidation, useIsVisible, useRepeatScope, useStateBinding, useStateStore, useStateValue, useUIStream, useValidation, useVisibility };