Skip to content

expand supported SwiftUI views - #23

Merged
0xWDG merged 4 commits into
mainfrom
additions-and-better-json-handling
Aug 20, 2026
Merged

0xWDG merged 4 commits into
mainfrom
additions-and-better-json-handling

Conversation

@0xWDG

@0xWDG 0xWDG commented Aug 20, 2026

Copy link
Copy Markdown
Owner
  • added 15 new JSON-backed SwiftUI components
  • log and skip unsupported view types without failing rendering ignore metadata objects without a type
  • added more previews, documentation, tests, and playground examples

added 15 new JSON-backed SwiftUI components
log and skip unsupported view types without failing rendering
ignore metadata objects without a type
added more previews, documentation, tests, and playground examples
Copilot AI lite review requested due to automatic review settings August 20, 2026 09:04
@0xWDG 0xWDG self-assigned this Aug 20, 2026
@0xWDG 0xWDG added the enhancement New feature or request label Aug 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Expands DynamicUI’s JSON-to-SwiftUI renderer by adding many new supported view types, improving decoding resilience (ignoring metadata-only entries), and documenting/previewing the new components across DocC, previews, tests, and the playground.

Changes:

  • Adds new JSON-backed SwiftUI components (e.g., AsyncImage, Link/ShareLink, Menu, NavigationStack/NavigationLink, Grid/GridRow, Lazy stacks/grids, Stepper, DatePicker, ColorPicker).
  • Updates decoding/rendering to ignore objects without a string type and to log-and-skip unsupported types instead of failing the full render.
  • Extends tests, DocC, previews, README, and playground demos to cover the expanded component set.

Reviewed changes

Copilot reviewed 57 out of 57 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Tests/DynamicUITests/DynamicUITests.swift Adds coverage for supported-type registry and metadata-ignoring decode behavior.
Sources/DynamicUI/Views/DynamicZStack.swift Adds Debug preview fixture for ZStack.
Sources/DynamicUI/Views/DynamicVStack.swift Adds Debug preview fixture for VStack.
Sources/DynamicUI/Views/DynamicVSplitView.swift Adds Debug preview fixture for VSplitView.
Sources/DynamicUI/Views/DynamicToggle.swift Switches to compatibility dynamicUIOnChange wrapper.
Sources/DynamicUI/Views/DynamicTextField.swift Switches to compatibility dynamicUIOnChange + adds preview.
Sources/DynamicUI/Views/DynamicTextEditor.swift Switches to compatibility dynamicUIOnChange + adds preview.
Sources/DynamicUI/Views/DynamicTEMPLATE.swift Adds template preview (debug-only).
Sources/DynamicUI/Views/DynamicTabView.swift Adds TabView preview fixture.
Sources/DynamicUI/Views/DynamicStepper.swift Introduces Stepper component with platform fallbacks + preview.
Sources/DynamicUI/Views/DynamicSlider.swift Switches to compatibility dynamicUIOnChange wrapper.
Sources/DynamicUI/Views/DynamicShareLink.swift Introduces ShareLink component with fallbacks + preview.
Sources/DynamicUI/Views/DynamicSecureTextField.swift Switches to compatibility dynamicUIOnChange + adds preview.
Sources/DynamicUI/Views/DynamicScrollView.swift Adds ScrollView preview fixture.
Sources/DynamicUI/Views/DynamicPicker.swift Switches to compatibility dynamicUIOnChange + adds preview.
Sources/DynamicUI/Views/DynamicNavigationView.swift Adds NavigationView preview fixture.
Sources/DynamicUI/Views/DynamicNavigationStack.swift Introduces NavigationStack component with fallback + preview.
Sources/DynamicUI/Views/DynamicNavigationSplitView.swift Adds NavigationSplitView preview fixture.
Sources/DynamicUI/Views/DynamicNavigationLink.swift Introduces NavigationLink component + preview.
Sources/DynamicUI/Views/DynamicMenu.swift Introduces Menu component with platform fallbacks + preview.
Sources/DynamicUI/Views/DynamicLink.swift Introduces Link component + preview.
Sources/DynamicUI/Views/DynamicLazyVStack.swift Introduces LazyVStack component + preview.
Sources/DynamicUI/Views/DynamicLazyVGrid.swift Introduces LazyVGrid component.
Sources/DynamicUI/Views/DynamicLazyHStack.swift Introduces LazyHStack component + preview.
Sources/DynamicUI/Views/DynamicLazyHGrid.swift Introduces LazyHGrid component and shared grid configuration.
Sources/DynamicUI/Views/DynamicLabel.swift Adds Label preview fixture.
Sources/DynamicUI/Views/DynamicInvalidTest.swift Adds debug-only “invalid JSON” preview fixture.
Sources/DynamicUI/Views/DynamicImage.swift Adds Image preview fixture.
Sources/DynamicUI/Views/DynamicGridRow.swift Introduces GridRow component with fallback + preview.
Sources/DynamicUI/Views/DynamicGrid.swift Introduces Grid component with fallback + preview.
Sources/DynamicUI/Views/DynamicDatePicker.swift Introduces DatePicker component with platform fallbacks + ISO8601 handling + preview.
Sources/DynamicUI/Views/DynamicColorPicker.swift Introduces ColorPicker component + color serialization + preview.
Sources/DynamicUI/Views/DynamicAsyncImage.swift Introduces AsyncImage component with loading/failure states + preview.
Sources/DynamicUI/Helpers/PreviewFixtures.swift Adds shared preview fixture helpers (debug-only).
Sources/DynamicUI/Helpers/DynamicUIHelper.swift Adds hex color parsing + Color→hex serialization.
Sources/DynamicUI/Extensions/View.modifiers.swift Adds dynamicUIOnChange wrapper for new/old SwiftUI onChange APIs.
Sources/DynamicUI/DynamicUIViewType.swift Adds centralized registry of supported view types.
Sources/DynamicUI/DynamicUIComponent.swift Adds metadata-tolerant decode entry wrapper + layout decoder helper.
Sources/DynamicUI/DynamicUI.swift Switches to registry-based view dispatch and logs unsupported types; uses layout decoder.
Sources/DynamicUI/DynamicUI.docc/Views/Stepper.md Adds Stepper documentation.
Sources/DynamicUI/DynamicUI.docc/Views/ShareLink.md Adds ShareLink documentation.
Sources/DynamicUI/DynamicUI.docc/Views/NavigationStack.md Adds NavigationStack documentation.
Sources/DynamicUI/DynamicUI.docc/Views/NavigationLink.md Adds NavigationLink documentation.
Sources/DynamicUI/DynamicUI.docc/Views/Menu.md Adds Menu documentation.
Sources/DynamicUI/DynamicUI.docc/Views/Link.md Adds Link documentation.
Sources/DynamicUI/DynamicUI.docc/Views/LazyVStack.md Adds LazyVStack documentation.
Sources/DynamicUI/DynamicUI.docc/Views/LazyVGrid.md Adds LazyVGrid documentation.
Sources/DynamicUI/DynamicUI.docc/Views/LazyHStack.md Adds LazyHStack documentation.
Sources/DynamicUI/DynamicUI.docc/Views/LazyHGrid.md Adds LazyHGrid documentation.
Sources/DynamicUI/DynamicUI.docc/Views/GridRow.md Adds GridRow documentation.
Sources/DynamicUI/DynamicUI.docc/Views/Grid.md Adds Grid documentation.
Sources/DynamicUI/DynamicUI.docc/Views/DatePicker.md Adds DatePicker documentation.
Sources/DynamicUI/DynamicUI.docc/Views/ColorPicker.md Adds ColorPicker documentation.
Sources/DynamicUI/DynamicUI.docc/Views/AsyncImage.md Adds AsyncImage documentation.
Sources/DynamicUI/DynamicUI.docc/DynamicUI.md Updates schema/behavior docs and adds links for new components.
README.md Updates high-level behavior notes (logging/skipping unknown types; ignore metadata entries).
Playground/DynamicUI Playground/ContentView.swift Adds “Custom” demo and expands sample JSON to include new views; improves editor/preview layout.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 14 to +18
public struct DynamicUIComponent: Codable, Hashable {
private enum CodingKeys: String, CodingKey {
case type
case title
case text
Comment on lines +37 to +44
let count = min(max(component.parameters?[countKey]?.toInt() ?? 1, 1), 50)
let minimum = max(component.parameters?["minimum"]?.toDouble() ?? 10, 0)
let maximum = max(component.parameters?["maximum"]?.toDouble() ?? .infinity, minimum)
let spacing = spacing(for: component)
let item = GridItem(
.flexible(minimum: minimum, maximum: maximum),
spacing: spacing
)
Copilot AI review requested due to automatic review settings August 20, 2026 09:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 57 out of 57 changed files in this pull request and generated no new comments.

Suppressed comments (3)

Sources/DynamicUI/DynamicUI.docc/DynamicUI.md:130

  • The “Controls” DocC links are missing the Views/ prefix, so they won’t match the article paths under DynamicUI.docc/Views/.
- <doc:Button>
- <doc:Toggle>
- <doc:TextField>
- <doc:SecureField>
- <doc:TextEditor>

Sources/DynamicUI/DynamicUI.docc/DynamicUI.md:147

  • The “Containers” DocC links are also missing the Views/ prefix; update them to match the article locations under DynamicUI.docc/Views/ so the links resolve.
- <doc:VStack>
- <doc:HStack>
- <doc:ZStack>
- <doc:LazyVStack>
- <doc:LazyHStack>

Sources/DynamicUI/DynamicUI.docc/DynamicUI.md:122

  • The DocC links under “Supported Views” point to <doc:Text> etc, but the articles live under DynamicUI.docc/Views/ (e.g. Views/Text.md). These links will likely be unresolved; include the Views/ path in the identifiers.

This issue also appears in the following locations of the same file:

  • line 126
  • line 143
- <doc:Text>
- <doc:Label>
- <doc:Image>
- <doc:AsyncImage>
- <doc:Divider>

Copilot AI review requested due to automatic review settings August 20, 2026 09:14
@0xWDG
0xWDG merged commit f1dfffe into main Aug 20, 2026
5 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 58 out of 58 changed files in this pull request and generated no new comments.

Suppressed comments (6)

Sources/DynamicUI/DynamicUI.swift:170

  • Filtering components and then using visibleComponents.indices as the ForEach identity can cause unstable view identity when conditions toggle (indexes shift when an item is hidden/shown), which can lead to SwiftUI reusing the wrong subview/state for a different component.
    /// - Returns: A SwiftUI View
    func buildView(for components: [DynamicUIComponent]) -> some View {
        // swiftlint:disable:previous cyclomatic_complexity function_body_length

Sources/DynamicUI/DynamicUI.swift:313

  • unsupportedView(for:) logs from inside the view-building path. Because buildView may be evaluated frequently by SwiftUI, this can generate repeated error logs for the same unsupported type and spam unified logging in production.
        }
    }

Sources/DynamicUI/Views/DynamicStepper.swift:32

  • Using .leastNonzeroMagnitude as the minimum step means a JSON step of 0 (or negative) will become an extremely tiny increment, which can make the Stepper practically unusable and generate huge numbers of intermediate values.
    Sources/DynamicUI/Views/DynamicLink.swift:23
  • DynamicLink accepts any URL scheme. If JSON comes from an untrusted source, this can enable links to non-web schemes (e.g. tel:, custom deep links, or other handlers). Consider restricting to an allow-list (similar to DynamicAsyncImage only allowing http/https), or making allowed schemes configurable.
    Sources/DynamicUI/Views/DynamicShareLink.swift:23
  • DynamicShareLink accepts any URL scheme. If layouts are driven by remote/untrusted JSON, consider validating schemes (e.g. http/https allow-list) before constructing a ShareLink/fallback Link, to avoid sharing or opening unintended URL types.
    Tests/DynamicUITests/DynamicUITests.swift:5
  • This test name says it verifies "documented" views, but the expected set is hard-coded rather than derived from the documentation source. Renaming the test would make its intent accurate and reduce confusion.

Copilot AI review requested due to automatic review settings August 20, 2026 09:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 58 out of 58 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Sources/DynamicUI/DynamicUI.swift:317

  • unsupportedView(for:) logs an OSLog .error message with privacy: .public for a value coming from external JSON. This can unnecessarily surface untrusted input in customer logs and elevate it to error severity; consider logging at warning (or lower) and relying on the default private redaction for interpolated values.
    private func unsupportedView(for type: String) -> EmptyView {
        Self.logger.error("Unsupported DynamicUI view type: \(type, privacy: .public)")
        return EmptyView()

Tests/DynamicUITests/DynamicUITests.swift:61

  • New hex color support in DynamicUIHelper.translateColor/translateHexColor is not currently covered by tests. Adding a small unit test for valid/invalid hex strings will help prevent regressions in ColorPicker defaults and modifier parsing.

0xWDG added a commit that referenced this pull request Oct 7, 2026
0xWDG added a commit that referenced this pull request Oct 7, 2026
0xWDG added a commit that referenced this pull request Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants