diff --git a/JSON_EXPRESSION_SYSTEM.md b/JSON_EXPRESSION_SYSTEM.md new file mode 100644 index 0000000..18b019f --- /dev/null +++ b/JSON_EXPRESSION_SYSTEM.md @@ -0,0 +1,62 @@ +# JSON Expression System + +This document describes the supported JSON expression patterns used across JSON UI schemas. +Legacy compute functions have been removed in favor of expression strings and value templates. + +## Core Concepts + +### Expressions + +Expressions are string values that resolve against a data + event context: + +```json +{ + "expression": "event.target.value" +} +``` + +Supported expression patterns: + +- `data` or `event` +- Dot access: `data.user.name`, `event.target.value` +- Literals: numbers, booleans, `null`, `undefined`, quoted strings +- Time: `Date.now()` +- Array filtering: + - `data.todos.filter(completed === true)` + - `data.users.filter(status === 'active').length` + +### Value Templates + +Value templates are JSON objects whose string values are evaluated as expressions: + +```json +{ + "valueTemplate": { + "id": "Date.now()", + "text": "data.newTodo", + "completed": false + } +} +``` + +### Conditions + +Conditions use expression strings that are evaluated against the data context: + +```json +{ + "condition": "data.newTodo.length > 0" +} +``` + +Supported condition patterns: + +- `data.field > 0` +- `data.field.length > 0` +- `data.field === 'value'` +- `data.field != null` + +## Legacy Compute Functions (Removed) + +Schemas should no longer reference function names in `compute`, `transform`, or string-based +condition fields. Use `expression` and `valueTemplate` instead. diff --git a/src/components/DataBindingDesigner.tsx b/src/components/DataBindingDesigner.tsx index 1c32c81..b2fa87a 100644 --- a/src/components/DataBindingDesigner.tsx +++ b/src/components/DataBindingDesigner.tsx @@ -7,30 +7,9 @@ import { ComponentBindingsCard } from '@/components/data-binding-designer/Compon import { HowItWorksCard } from '@/components/data-binding-designer/HowItWorksCard' import dataBindingCopy from '@/data/data-binding-designer.json' -interface SeedDataSource extends Omit { - computeId?: string -} - -const computeRegistry: Record) => any> = { - displayName: (data) => `Welcome, ${data.userProfile?.name || 'Guest'}!`, -} - -const buildSeedDataSources = (sources: SeedDataSource[]): DataSource[] => { - return sources.map((source) => { - if (source.type === 'computed' && source.computeId) { - return { - ...source, - compute: computeRegistry[source.computeId], - } - } - - return source - }) -} - export function DataBindingDesigner() { const [dataSources, setDataSources] = useState( - buildSeedDataSources(dataBindingCopy.seed.dataSources as SeedDataSource[]), + dataBindingCopy.seed.dataSources as DataSource[], ) const [mockComponents] = useState(dataBindingCopy.seed.components) diff --git a/src/components/molecules/data-source-editor/ComputedSourceFields.tsx b/src/components/molecules/data-source-editor/ComputedSourceFields.tsx index 17019ec..fa70389 100644 --- a/src/components/molecules/data-source-editor/ComputedSourceFields.tsx +++ b/src/components/molecules/data-source-editor/ComputedSourceFields.tsx @@ -6,9 +6,12 @@ import { DataSource } from '@/types/json-ui' import { X } from '@phosphor-icons/react' interface ComputedSourceFieldsCopy { - computeLabel: string - computePlaceholder: string - computeHelp: string + expressionLabel: string + expressionPlaceholder: string + expressionHelp: string + valueTemplateLabel: string + valueTemplatePlaceholder: string + valueTemplateHelp: string dependenciesLabel: string availableSourcesLabel: string emptyDependencies: string @@ -38,22 +41,37 @@ export function ComputedSourceFields({ return ( <>
- +