Skip to content

feat: Style dictionary context models#69

Draft
lebojo wants to merge 2 commits intofeat/ios/build-tokensfrom
feat/ios/sd-context-models
Draft

feat: Style dictionary context models#69
lebojo wants to merge 2 commits intofeat/ios/build-tokensfrom
feat/ios/sd-context-models

Conversation

@lebojo
Copy link
Copy Markdown
Member

@lebojo lebojo commented Mar 24, 2026

This PR add Style dictionary context and model to export tokens to swift (SwiftUI)

@lebojo lebojo self-assigned this Mar 24, 2026
@lebojo
Copy link
Copy Markdown
Member Author

lebojo commented Mar 24, 2026

Depends on #67

@github-actions
Copy link
Copy Markdown
Contributor

⏭️ Storybook build skipped

  • Reason: pull request is still in draft
  • Changed files inspected: 5
  • Workflow run: View details

Storybook build was intentionally skipped for this PR event.

Relevant files

  • packages/tokens/scripts/scripts/build-tokens/src/build/outputs/swift/context.ts
  • packages/tokens/scripts/scripts/build-tokens/src/build/outputs/swift/helpers.ts
  • packages/tokens/scripts/scripts/build-tokens/src/build/outputs/swift/model.ts
  • packages/tokens/scripts/scripts/build-tokens/src/build/outputs/swift/parser.ts
  • packages/tokens/scripts/scripts/build-tokens/src/build/outputs/swift/transforms.ts

@github-actions
Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Data Loss in Color Resolution

The resolveColorExpression function returns .clear for non-T1 tokens (T2/T3) that have direct color values instead of token references. This effectively discards valid color data if a semantic or component token defines a color directly rather than referencing a primitive token. The logic should handle direct values for all token tiers or explicitly warn about this constraint.

function resolveColorExpression(
    token: TransformedToken,
    bySwiftName: Map<string, TransformedToken>,
    depth = 0,
): string {
    if (depth > 10) return '.clear';

    const original = token.original?.$value;
    if (!isTokenReference(original)) {
        if (isT1Token(token)) return xcassetsColorRef(token);
        return '.clear';
    }

    const refPath = original.slice(1, -1).split('.');
    const refName = toSwiftName(refPath);
    const refToken = bySwiftName.get(refName);

    if (refToken) {
        if (isT2Token(refToken)) return `Self.${refName}`;
        return resolveColorExpression(refToken, bySwiftName, depth + 1);
    }

    return xcassetsColorRefFromPath(refPath);
}
Missing JSON Error Handling

The custom parser performs JSON.parse(contents) without a try-catch block. If a token file contains malformed JSON, this will throw an unhandled exception with no indication of which file caused the failure, making debugging difficult in large token sets.

const data = JSON.parse(contents);
Potential Naming Collision

The cleanSegment function strips all non-alphanumeric characters (except dashes) before converting to camelCase. This can cause naming collisions if token paths differ only by special characters (e.g., color-red and color_red both become colorred), potentially leading to duplicate Swift property names or incorrect references.

function cleanSegment(s: string): string {
    return s.replace(/[^a-zA-Z0-9-]/g, '').replace(/-([a-zA-Z0-9])/g, (_, c: string) => c.toUpperCase());
}

@github-actions
Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant