view-contracts 0.3.4 → 0.4.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.
Files changed (45) hide show
  1. package/README.md +10 -3
  2. package/cli-contract.yaml +41 -1
  3. package/dist/preview-style-helpers.js +2 -0
  4. package/dist/preview-style-helpers.js.map +7 -0
  5. package/dist/preview.mjs +153 -0
  6. package/dist/preview.mjs.map +7 -0
  7. package/dist/view-contracts.bundle.mjs +402 -237
  8. package/dist/view-contracts.bundle.mjs.map +4 -4
  9. package/docs/cli-reference.md +37 -1
  10. package/package.json +28 -1
  11. package/renderers/compose/renderRuntime.ts +40 -0
  12. package/renderers/react/defaults/theme.yaml +23 -0
  13. package/renderers/react/defaults/tokens.yaml +15 -0
  14. package/renderers/react/elementMap.ts +30 -6
  15. package/renderers/react/elements.yaml +17 -5
  16. package/renderers/react/lowering/foldStyle.ts +13 -1
  17. package/renderers/react/lowering/lowerToJsx.ts +58 -40
  18. package/renderers/react/paths.ts +1 -10
  19. package/renderers/react/preview/components.ts +23 -0
  20. package/renderers/react/preview/index.ts +3 -0
  21. package/renderers/react/preview/start.tsx +42 -0
  22. package/renderers/react/preview/style-helpers.ts +5 -0
  23. package/renderers/react/preview/vocabulary.tsx +75 -0
  24. package/renderers/react/renderComponents.ts +169 -14
  25. package/renderers/react/runtime/theme.css +9 -17
  26. package/renderers/react/style/foldLiterals.ts +11 -0
  27. package/renderers/swiftui/README.md +48 -10
  28. package/renderers/swiftui/elementMap.ts +45 -0
  29. package/renderers/swiftui/elements.yaml +82 -0
  30. package/renderers/swiftui/index.ts +5 -0
  31. package/renderers/swiftui/lowering/lowerToSwiftUI.ts +542 -0
  32. package/renderers/swiftui/lowering/modifiers.ts +142 -0
  33. package/renderers/swiftui/renderComponents.ts +79 -0
  34. package/renderers/swiftui/renderRuntime.ts +91 -0
  35. package/renderers/swiftui/renderTheme.ts +208 -0
  36. package/spec/ui-dsl.linter-rules.json +0 -7
  37. package/spec/ui-dsl.meta.json +5 -0
  38. package/spec/ui-dsl.schema.json +333 -259
  39. package/src/generated/schema/allowed-components.ts +0 -36
  40. package/src/generated/schema/dsl-enums.ts +0 -19
  41. package/src/generated/schema/dsl-properties.ts +0 -64
  42. package/src/generated/schema/index.ts +0 -4
  43. package/src/generated/schema/lowering-style-properties.ts +0 -35
  44. package/src/generated/schema/react-renderer-element-config.ts +0 -27
  45. package/src/generated/schema/schema-document.ts +0 -33
package/README.md CHANGED
@@ -111,19 +111,21 @@ The generated output is deterministic.
111
111
  ### Supported
112
112
 
113
113
  - React generation (`generated/react/` — screens, `runtime.ts`, `theme.css`, …)
114
+ - SwiftUI generation (`generated/swiftui/` — full DSL element coverage, theme variant dictionary, `SampleData.json` from mock YAML SSoT)
114
115
  - Design tokens + theme variants (`views/design/tokens.yaml`, `theme.yaml`)
115
116
  - Live DSL preview (`dev:preview`) with `views/preview/*.mock.yaml` sample data
116
117
  - Extension registry (`extensions.yaml`) with plain HTML/CSS implementations
117
118
  - In-memory View IR compilation
118
119
  - Standalone app scaffold (`.vite/` per example project)
120
+ - Table DSL with configurable `separator` / `separatorColor` / `border` / `borderColor`
121
+ - Dynamic variant resolution via `IrConcat` (runtime theme dictionary in SwiftUI)
119
122
 
120
123
  ### Planned
121
124
 
122
- - SwiftUI renderer
123
125
  - Jetpack Compose renderer
124
126
  - PDF renderer
125
127
 
126
- The contract model is designed for multi-target generation, but the first production target is React.
128
+ The contract model is designed for multi-target generation. React and SwiftUI are production-ready targets.
127
129
 
128
130
  ---
129
131
 
@@ -238,6 +240,11 @@ examples/admin-dashboard/
238
240
  │ └── preview/ # *.mock.yaml — preview sample ViewModels only
239
241
  ├── src/ # app wiring, extension components (HTML/CSS), handlers
240
242
  ├── generated/ # build output (standalone — no @view-contracts imports)
243
+ │ ├── react/ # React generated code
244
+ │ └── swiftui/ # SwiftUI generated code + SampleData.json
245
+ ├── ios-preview/ # SwiftUI preview app (XcodeGen project)
246
+ │ ├── Sources/ # ContentView, ViewModels (Codable, loads SampleData.json)
247
+ │ └── project.yml # XcodeGen definition
241
248
  ├── contracts/ # OpenAPI + micro-contracts config
242
249
  ├── extensions.yaml # extension registry (Grid, Table, …)
243
250
  ├── dev.ports.ts # fixed dev server ports
@@ -270,7 +277,7 @@ packages/
270
277
 
271
278
  renderers/
272
279
  ├── react/ # lowering, element map, runtime, templates
273
- ├── swiftui/ # (planned)
280
+ ├── swiftui/ # lowering, theme dictionary, modifier cascade
274
281
  └── compose/ # (planned)
275
282
 
276
283
  docs/
package/cli-contract.yaml CHANGED
@@ -3,7 +3,7 @@ cli_contracts: 0.1.0
3
3
 
4
4
  info:
5
5
  title: view-contracts CLI
6
- version: 0.3.3
6
+ version: 0.3.5
7
7
  description: >-
8
8
  Contract-first UI design toolchain. Compiles restricted view-contract TSX
9
9
  to language-neutral View IR and renders platform targets (React, SwiftUI, Compose).
@@ -162,3 +162,43 @@ command_sets:
162
162
  description: Lint passed.
163
163
  '1':
164
164
  description: Lint failed.
165
+
166
+ preview:
167
+ summary: Start DSL preview HTTP server.
168
+ description: >-
169
+ Compiles views/*.view.tsx on demand and serves a React preview over HTTP.
170
+ No Vite setup required in the consumer project.
171
+ usage:
172
+ - view-contracts preview
173
+ - view-contracts preview -c view-contracts.config.yaml
174
+ - view-contracts preview --port 3000 --screen AdminDashboard
175
+ options:
176
+ - name: config
177
+ aliases: [c]
178
+ description: Path to view-contracts.config.yaml (discovered upward from cwd when omitted).
179
+ value_name: path
180
+ schema:
181
+ type: string
182
+ - name: port
183
+ aliases: [p]
184
+ description: HTTP listen port.
185
+ value_name: number
186
+ schema:
187
+ type: integer
188
+ default: 5173
189
+ - name: host
190
+ description: HTTP listen host.
191
+ value_name: address
192
+ schema:
193
+ type: string
194
+ default: 127.0.0.1
195
+ - name: screen
196
+ description: Screen name from view-bindings.yaml (default first react target).
197
+ value_name: name
198
+ schema:
199
+ type: string
200
+ exits:
201
+ '0':
202
+ description: Server stopped normally.
203
+ '1':
204
+ description: Startup or compile failed.
@@ -0,0 +1,2 @@
1
+ function o(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}var a=new Set(["default","muted"]);function i(t,n){let e=t??n;return!e||a.has(e)?"default":e}function f(t,n){let e=`vc-${o(t)}`,s=i(n?.variant,n?.tone),r=[e,`${e}--${s}`];return n?.extra&&r.push(n.extra),r.filter(Boolean).join(" ")}export{f as extensionClassName,i as resolveExtensionVariant};
2
+ //# sourceMappingURL=preview-style-helpers.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../renderers/react/runtime/style.ts"],
4
+ "sourcesContent": ["/** Map flex alignment shorthand to CSS align-items / align-self values. */\nexport function mapAlign(value?: string): string | undefined {\n if (!value) return undefined;\n if (value === 'start') return 'flex-start';\n if (value === 'end') return 'flex-end';\n return value;\n}\n\n/** Map flex justification shorthand to CSS justify-content values. */\nexport function mapJustify(value?: string): string | undefined {\n if (!value) return undefined;\n if (value === 'start') return 'flex-start';\n if (value === 'end') return 'flex-end';\n if (value === 'between' || value === 'spaceBetween') return 'space-between';\n if (value === 'around' || value === 'spaceAround') return 'space-around';\n if (value === 'spaceEvenly') return 'space-evenly';\n return value;\n}\n\n/** Preview vocabulary helper \u2014 production lowered JSX uses visibility guards instead. */\nexport function isHidden(props: { visible?: boolean; hidden?: boolean }): boolean {\n return props.hidden === true || props.visible === false;\n}\n\n/** Sample/extension helper for preview tone class names. */\nexport function toneClass(tone: string | undefined): string {\n return tone ? `ui-tone-${tone}` : 'ui-tone-default';\n}\n\nfunction componentToKebab(name: string): string {\n return name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nconst DEFAULT_VARIANT_ALIASES = new Set(['default', 'muted']);\n\n/** Resolve theme variant name from variant or legacy tone prop. */\nexport function resolveExtensionVariant(variant?: string, tone?: string): string {\n const raw = variant ?? tone;\n if (!raw || DEFAULT_VARIANT_ALIASES.has(raw)) return 'default';\n return raw;\n}\n\n/** Build vc-* base + --variant modifier for themed extension components. */\nexport function extensionClassName(\n component: string,\n options?: { variant?: string; tone?: string; extra?: string | false },\n): string {\n const base = `vc-${componentToKebab(component)}`;\n const variant = resolveExtensionVariant(options?.variant, options?.tone);\n const parts = [base, `${base}--${variant}`];\n if (options?.extra) parts.push(options.extra);\n return parts.filter(Boolean).join(' ');\n}\n"],
5
+ "mappings": "AA6BA,SAASA,EAAiBC,EAAsB,CAC9C,OAAOA,EAAK,QAAQ,kBAAmB,OAAO,EAAE,YAAY,CAC9D,CAEA,IAAMC,EAA0B,IAAI,IAAI,CAAC,UAAW,OAAO,CAAC,EAGrD,SAASC,EAAwBC,EAAkBC,EAAuB,CAC/E,IAAMC,EAAMF,GAAWC,EACvB,MAAI,CAACC,GAAOJ,EAAwB,IAAII,CAAG,EAAU,UAC9CA,CACT,CAGO,SAASC,EACdC,EACAC,EACQ,CACR,IAAMC,EAAO,MAAMV,EAAiBQ,CAAS,CAAC,GACxCJ,EAAUD,EAAwBM,GAAS,QAASA,GAAS,IAAI,EACjEE,EAAQ,CAACD,EAAM,GAAGA,CAAI,KAAKN,CAAO,EAAE,EAC1C,OAAIK,GAAS,OAAOE,EAAM,KAAKF,EAAQ,KAAK,EACrCE,EAAM,OAAO,OAAO,EAAE,KAAK,GAAG,CACvC",
6
+ "names": ["componentToKebab", "name", "DEFAULT_VARIANT_ALIASES", "resolveExtensionVariant", "variant", "tone", "raw", "extensionClassName", "component", "options", "base", "parts"]
7
+ }