CatalogRenderer.svelte 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. <script module lang="ts">
  2. import type { ComputedFunction, DirectiveDefinition, Spec, StateStore } from "@json-render/core";
  3. import type { ComponentRenderer, ComponentRegistry } from "./renderer.js";
  4. export interface CatalogRendererProps {
  5. spec: Spec | null;
  6. registry: ComponentRegistry;
  7. store?: StateStore;
  8. state?: Record<string, unknown>;
  9. onAction?: (actionName: string, params?: Record<string, unknown>) => void;
  10. onStateChange?: (changes: Array<{ path: string; value: unknown }>) => void;
  11. functions?: Record<string, ComputedFunction>;
  12. /** Custom directives for user-defined `$`-prefixed dynamic values */
  13. directives?: DirectiveDefinition[];
  14. loading?: boolean;
  15. fallback?: ComponentRenderer;
  16. }
  17. </script>
  18. <script lang="ts">
  19. import type { ActionHandler } from "@json-render/core";
  20. import JsonUIProvider from "./JsonUIProvider.svelte";
  21. import Renderer from "./Renderer.svelte";
  22. let {
  23. spec,
  24. registry,
  25. store,
  26. state,
  27. onAction,
  28. onStateChange,
  29. functions,
  30. directives,
  31. loading = false,
  32. fallback,
  33. }: CatalogRendererProps = $props();
  34. let actionHandlers = $derived.by(() => {
  35. if (!onAction) return undefined;
  36. // Wrap onAction with a Proxy so any action name routes to the callback
  37. return new Proxy({} as Record<string, ActionHandler>, {
  38. get: (_target, prop: string) => {
  39. return (params: Record<string, unknown>) => onAction(prop, params);
  40. },
  41. has: () => true,
  42. });
  43. });
  44. </script>
  45. <JsonUIProvider
  46. {registry}
  47. {store}
  48. initialState={state}
  49. handlers={actionHandlers}
  50. {functions}
  51. {directives}
  52. {onStateChange}>
  53. <Renderer {spec} {registry} {loading} {fallback} />
  54. </JsonUIProvider>