Code Block and Compound Button Card improvements to close in on parity with Web#69
Open
vallesmarinerisapp wants to merge 257 commits into
Open
Code Block and Compound Button Card improvements to close in on parity with Web#69vallesmarinerisapp wants to merge 257 commits into
vallesmarinerisapp wants to merge 257 commits into
Conversation
…ment Regenerated all 1033 Paparazzi snapshot baselines to reflect the updated hostConfig design tokens (button colors from hostConfig, table grid lines from separator config, corner radii, spacing).
…, Icon element Major changes across both platforms: **Figma Alignment (both platforms):** - Add badgeStyles (7 styles x filled/tint) and pageControl to HostConfig - Fix iOS container styles: remove extra borderColors, correct attention/accent bg - Fix Android showCard.style: Emphasis → Default per Figma spec **Bookmark Feature (both platforms):** - Persistent bookmark store (UserDefaults on iOS, SharedPreferences on Android) - Bookmark toggle on gallery card rows and detail view toolbar - New Bookmarks screen in More tab with remove support - Android gallery scroll position preserved across navigation **iOS SDK Integration:** - Wire ACRendering + ACCore SPM packages into SampleApp Xcode project - Replace custom CardPreviewPlaceholder with SDK AdaptiveCardView - Sample app now uses full SDK renderer (matching Android architecture) **Parsing Fixes (iOS):** - Add Spacing.ExtraSmall enum case - Add ImageStyle.RoundedCorners enum case - Fix TargetElement decoder to accept both string and object formats **Icon Element (iOS):** - New IconElement model in ACCore - New IconElementView renderer with 100+ Fluent UI → SF Symbol mappings - Resolves "Unknown element type: Icon" across 159 card elements
- test-card-parsing.swift: validates all card JSONs parse without errors - test-ios-cards-ui.sh: checks cards for unknown element types and reports Results: 634 cards tested, 628 pass, 6 warnings (intentional test cards)
Self-healing loop: ran CardParsingRegressionTests against 634 cards,
found 60+ parsing failures, fixed ALL to 0 failures.
Parsing fixes:
- CaseInsensitiveCodable: fallback to default instead of throwing
(handles template expressions like ${if(...)})
- CompoundButton.icon: accept both string and {name,size,color} object
- RichTextBlock.inlines: accept plain strings as TextRun shorthand
- CardElement.fallback: handle "drop" string per AC spec
- TextBlock.text: make optional (some cards omit it)
- ProgressBar.value: make optional
- ActionStyle: add "other" case
- CardAction: add .unknown case for graceful fallback
- TargetElement: accept string shorthand
- Input.isRequired: decode from string "true"/"false"
- AdaptiveCard.body/actions: skip non-array values gracefully
- Image.themedUrls: handle array format
- Carousel.pages: handle template string expressions
- PopoverAction.popoverBody: make optional
Repo changes:
- Add ios/SampleApp.xcodeproj to git (exception in .gitignore)
- Add CardParsingRegressionTests (4 test groups, 634 cards)
- Add test scripts: auto-test-ios-cards.sh, test-ios-cards-visual.sh
… testing
- Add adaptivecards://card/{path} URL scheme for programmatic navigation
- DeepLinkRouter handles URL → card detail view via fullScreenCover
- visual-test-loop.sh: automated screenshot capture for all Teams Official cards
Uses simctl openurl + simctl io screenshot — no accessibility permissions needed
- All 19 Teams Official cards render successfully (visual verification)
Remaining minor issues (tracked for future):
- Badge element type not yet supported (shows "Unknown element type: Badge")
- Some Fluent icon names need additional SF Symbol mappings
- Network images (person photos, hero images) depend on connectivity
Documents the adaptivecards:// URL scheme, automated visual test loop, and card parsing regression test commands for developer reference.
bash shared/scripts/self-heal-ios.sh — full automated test cycle: Phase 1: Parse regression (swift test --filter CardParsingRegressionTests) Phase 2: Visual smoke (deep-link → screenshot → analyze each card) Phase 3: Markdown report with per-card status + screenshots Modes: --parse-only, --visual-only, --card <name> Results: 19/19 Teams Official cards pass (0 failures)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…antSingh01#50) * fix(ios): align TeamsHostConfig to Figma iOS design spec Update iOS TeamsHostConfig values to match the platform-specific HostConfig from the Figma AC-Evolution design file (iOS page). Key changes from Figma iOS Light spec: - fontFamily: Segoe UI → .SF UI Text (iOS system font) - fontSizes: 12/14/14/16/20 → 12/15/15/17/22 - fontWeights: lighter 400→300, bolder 500→600 - separator lineColor: #0D16233A → #FFDFDEDE - spacing: default 8→10, padding 10→8 - factSet spacing: 32→16 - container backgrounds: good #DFF6DD→#E7F2DA, warning #FED9CC→#FBF6D9 - monospace font: Courier New → Menlo - actions: spacing Medium→Default, showCard style Emphasis→Default Also updates README with Phase 6A.1 Figma Design Alignment milestone and refreshes build/test status to 2026-03-10. * fix(ios,android): replace hardcoded design values with hostConfig Audit all rendering views against Figma spec and replace hardcoded colors, spacing, corner radii, and border widths with hostConfig values. iOS fixes: - ActionButton: spacing, padding, cornerRadius, borderWidth from hostConfig - ActionButton: refactor sfSymbol switch to dictionary (fixes SwiftLint cyclomatic complexity violation) - ActionSetView: overflow menu uses hostConfig spacing/radius/thickness - CodeBlockView: all padding uses hostConfig.spacing.small - CompoundButtonView: border lineWidth from hostConfig.separator - AccordionView: divider height from hostConfig.separator.lineThickness - ProgressIndicatorViews: spinner spacing from hostConfig.spacing.default Android fixes: - ActionSetView: positive/destructive button colors from hostConfig foregroundColors instead of hardcoded hex; cornerRadius, padding, border stroke, icon spacing all from hostConfig - MediaAndTableViews: table grid line color from hostConfig.separator; divider thickness from hostConfig.separator.lineThickness * chore(android): update Paparazzi snapshot baselines after Figma alignment Regenerated all 1033 Paparazzi snapshot baselines to reflect the updated hostConfig design tokens (button colors from hostConfig, table grid lines from separator config, corner radii, spacing). * feat(ios,android): bookmark feature, SDK integration, Figma alignment, Icon element Major changes across both platforms: **Figma Alignment (both platforms):** - Add badgeStyles (7 styles x filled/tint) and pageControl to HostConfig - Fix iOS container styles: remove extra borderColors, correct attention/accent bg - Fix Android showCard.style: Emphasis → Default per Figma spec **Bookmark Feature (both platforms):** - Persistent bookmark store (UserDefaults on iOS, SharedPreferences on Android) - Bookmark toggle on gallery card rows and detail view toolbar - New Bookmarks screen in More tab with remove support - Android gallery scroll position preserved across navigation **iOS SDK Integration:** - Wire ACRendering + ACCore SPM packages into SampleApp Xcode project - Replace custom CardPreviewPlaceholder with SDK AdaptiveCardView - Sample app now uses full SDK renderer (matching Android architecture) **Parsing Fixes (iOS):** - Add Spacing.ExtraSmall enum case - Add ImageStyle.RoundedCorners enum case - Fix TargetElement decoder to accept both string and object formats **Icon Element (iOS):** - New IconElement model in ACCore - New IconElementView renderer with 100+ Fluent UI → SF Symbol mappings - Resolves "Unknown element type: Icon" across 159 card elements * test(shared): add automated card parsing and UI smoke test scripts - test-card-parsing.swift: validates all card JSONs parse without errors - test-ios-cards-ui.sh: checks cards for unknown element types and reports Results: 634 cards tested, 628 pass, 6 warnings (intentional test cards) * fix(ios): resolve all card parsing failures + add xcodeproj to repo Self-healing loop: ran CardParsingRegressionTests against 634 cards, found 60+ parsing failures, fixed ALL to 0 failures. Parsing fixes: - CaseInsensitiveCodable: fallback to default instead of throwing (handles template expressions like ${if(...)}) - CompoundButton.icon: accept both string and {name,size,color} object - RichTextBlock.inlines: accept plain strings as TextRun shorthand - CardElement.fallback: handle "drop" string per AC spec - TextBlock.text: make optional (some cards omit it) - ProgressBar.value: make optional - ActionStyle: add "other" case - CardAction: add .unknown case for graceful fallback - TargetElement: accept string shorthand - Input.isRequired: decode from string "true"/"false" - AdaptiveCard.body/actions: skip non-array values gracefully - Image.themedUrls: handle array format - Carousel.pages: handle template string expressions - PopoverAction.popoverBody: make optional Repo changes: - Add ios/SampleApp.xcodeproj to git (exception in .gitignore) - Add CardParsingRegressionTests (4 test groups, 634 cards) - Add test scripts: auto-test-ios-cards.sh, test-ios-cards-visual.sh * feat(ios): deep link navigation + visual test loop for automated card testing - Add adaptivecards://card/{path} URL scheme for programmatic navigation - DeepLinkRouter handles URL → card detail view via fullScreenCover - visual-test-loop.sh: automated screenshot capture for all Teams Official cards Uses simctl openurl + simctl io screenshot — no accessibility permissions needed - All 19 Teams Official cards render successfully (visual verification) Remaining minor issues (tracked for future): - Badge element type not yet supported (shows "Unknown element type: Badge") - Some Fluent icon names need additional SF Symbol mappings - Network images (person photos, hero images) depend on connectivity * docs: add sample app deep link testing and visual test loop to CLAUDE.md Documents the adaptivecards:// URL scheme, automated visual test loop, and card parsing regression test commands for developer reference. * feat(testing): add self-healing iOS card test loop command bash shared/scripts/self-heal-ios.sh — full automated test cycle: Phase 1: Parse regression (swift test --filter CardParsingRegressionTests) Phase 2: Visual smoke (deep-link → screenshot → analyze each card) Phase 3: Markdown report with per-card status + screenshots Modes: --parse-only, --visual-only, --card <name> Results: 19/19 Teams Official cards pass (0 failures) * feat(testing): add self-healing test loops for iOS and Android Add automated detect → diagnose → recover → fix test scripts for both platforms. Each runs a 6-phase cycle: parse regression tests, visual smoke tests with deep-link navigation and screenshots, multi-signal crash/hang/OOM diagnosis from simulator logs (iOS) or logcat (Android), auto-retry with escalating recovery, structured fix suggestions with file-level hints, and a rich markdown report with all artifacts. iOS script uses xcrun simctl + system log mining; Android script uses adb + logcat analysis. Both support --parse-only, --visual-only, --card, --retry, and --category flags. * feat(ios,android): rendering fixes, input parity, and sample app improvements Container rendering: - Add showBorder and roundedCorners support to Container model and view on both platforms - Render border stroke using host config borderColor when showBorder is true Image rendering (Android): - Fix Auto-sized images to fill container width per AC spec (fillMaxWidth) - Use FillWidth content scale for aspect-ratio-preserving full-width images - Add RoundedCorners image style enum and 8dp corner radius rendering Input parity (iOS): - Fix DateInputView pre-populating today's date when no value specified - Fix TimeInputView pre-populating current time when no value specified - Both now show placeholder text until user explicitly selects a value - Add required field suffix (* indicator) to all input labels via host config Progress bar (iOS): - Fix named color resolution (green, accent, attention, etc.) in ProgressBarView - Color(hex:) was receiving named strings like "green" and falling back to black Icon mapping (Android): - Map "Crown" icon to WorkspacePremium instead of Star for better visual parity App icon: - Add custom app icon for both iOS (Assets.xcassets) and Android (mipmap resources) - Update AndroidManifest.xml with icon and roundIcon attributes - Add Assets.xcassets to Xcode project build phases Sample app enhancements: - Improved card gallery, detail screens, and Teams simulator on both platforms - Added input renderer setup, bookmarks, settings, and performance dashboard - Enhanced deep link navigation and self-healing test scripts * feat(ios,android): extended deep link routing, gallery filters, cart icon, and demo script Add full deep link navigation support (editor, performance, bookmarks, settings, more) on both platforms with gallery category filtering via adaptivecards://gallery/{filter}. Add cart/cartfilled icon mapping for parity. Include dual-platform demo-bookmarks.sh script for automated bookmark walkthroughs. Update README with latest sample app features and 52 test cards. ---------
* fix(ios): resolve all card parsing failures + add xcodeproj to repo
Self-healing loop: ran CardParsingRegressionTests against 634 cards,
found 60+ parsing failures, fixed ALL to 0 failures.
Parsing fixes:
- CaseInsensitiveCodable: fallback to default instead of throwing
(handles template expressions like ${if(...)})
- CompoundButton.icon: accept both string and {name,size,color} object
- RichTextBlock.inlines: accept plain strings as TextRun shorthand
- CardElement.fallback: handle "drop" string per AC spec
- TextBlock.text: make optional (some cards omit it)
- ProgressBar.value: make optional
- ActionStyle: add "other" case
- CardAction: add .unknown case for graceful fallback
- TargetElement: accept string shorthand
- Input.isRequired: decode from string "true"/"false"
- AdaptiveCard.body/actions: skip non-array values gracefully
- Image.themedUrls: handle array format
- Carousel.pages: handle template string expressions
- PopoverAction.popoverBody: make optional
Repo changes:
- Add ios/SampleApp.xcodeproj to git (exception in .gitignore)
- Add CardParsingRegressionTests (4 test groups, 634 cards)
- Add test scripts: auto-test-ios-cards.sh, test-ios-cards-visual.sh
* feat(ios): deep link navigation + visual test loop for automated card testing
- Add adaptivecards://card/{path} URL scheme for programmatic navigation
- DeepLinkRouter handles URL → card detail view via fullScreenCover
- visual-test-loop.sh: automated screenshot capture for all Teams Official cards
Uses simctl openurl + simctl io screenshot — no accessibility permissions needed
- All 19 Teams Official cards render successfully (visual verification)
Remaining minor issues (tracked for future):
- Badge element type not yet supported (shows "Unknown element type: Badge")
- Some Fluent icon names need additional SF Symbol mappings
- Network images (person photos, hero images) depend on connectivity
* docs: add sample app deep link testing and visual test loop to CLAUDE.md
Documents the adaptivecards:// URL scheme, automated visual test loop,
and card parsing regression test commands for developer reference.
* feat(testing): add self-healing iOS card test loop command
bash shared/scripts/self-heal-ios.sh — full automated test cycle:
Phase 1: Parse regression (swift test --filter CardParsingRegressionTests)
Phase 2: Visual smoke (deep-link → screenshot → analyze each card)
Phase 3: Markdown report with per-card status + screenshots
Modes: --parse-only, --visual-only, --card <name>
Results: 19/19 Teams Official cards pass (0 failures)
* feat(testing): add self-healing test loops for iOS and Android
Add automated detect → diagnose → recover → fix test scripts for both
platforms. Each runs a 6-phase cycle: parse regression tests, visual
smoke tests with deep-link navigation and screenshots, multi-signal
crash/hang/OOM diagnosis from simulator logs (iOS) or logcat (Android),
auto-retry with escalating recovery, structured fix suggestions with
file-level hints, and a rich markdown report with all artifacts.
iOS script uses xcrun simctl + system log mining; Android script uses
adb + logcat analysis. Both support --parse-only, --visual-only,
--card, --retry, and --category flags.
* feat(ios,android): rendering fixes, input parity, and sample app improvements
Container rendering:
- Add showBorder and roundedCorners support to Container model and view on both platforms
- Render border stroke using host config borderColor when showBorder is true
Image rendering (Android):
- Fix Auto-sized images to fill container width per AC spec (fillMaxWidth)
- Use FillWidth content scale for aspect-ratio-preserving full-width images
- Add RoundedCorners image style enum and 8dp corner radius rendering
Input parity (iOS):
- Fix DateInputView pre-populating today's date when no value specified
- Fix TimeInputView pre-populating current time when no value specified
- Both now show placeholder text until user explicitly selects a value
- Add required field suffix (* indicator) to all input labels via host config
Progress bar (iOS):
- Fix named color resolution (green, accent, attention, etc.) in ProgressBarView
- Color(hex:) was receiving named strings like "green" and falling back to black
Icon mapping (Android):
- Map "Crown" icon to WorkspacePremium instead of Star for better visual parity
App icon:
- Add custom app icon for both iOS (Assets.xcassets) and Android (mipmap resources)
- Update AndroidManifest.xml with icon and roundIcon attributes
- Add Assets.xcassets to Xcode project build phases
Sample app enhancements:
- Improved card gallery, detail screens, and Teams simulator on both platforms
- Added input renderer setup, bookmarks, settings, and performance dashboard
- Enhanced deep link navigation and self-healing test scripts
* feat(ios,android): extended deep link routing, gallery filters, cart icon, and demo script
Add full deep link navigation support (editor, performance, bookmarks, settings, more) on
both platforms with gallery category filtering via adaptivecards://gallery/{filter}. Add
cart/cartfilled icon mapping for parity. Include dual-platform demo-bookmarks.sh script for
automated bookmark walkthroughs. Update README with latest sample app features and 52 test cards.
* docs: Documentation updates with latest changes 3/11
* feat(ios,android): rename sample app to AC Visualizer
Rename the sample app from "Adaptive Cards Sample App" to
"AC Visualizer" across both platforms, including app display names,
hero headers, footer labels, Xcode target/scheme, scripts, and docs.
Verified on both iOS and Android simulators.
…1#55) * fix(ios): resolve all card parsing failures + add xcodeproj to repo Self-healing loop: ran CardParsingRegressionTests against 634 cards, found 60+ parsing failures, fixed ALL to 0 failures. Parsing fixes: - CaseInsensitiveCodable: fallback to default instead of throwing (handles template expressions like ${if(...)}) - CompoundButton.icon: accept both string and {name,size,color} object - RichTextBlock.inlines: accept plain strings as TextRun shorthand - CardElement.fallback: handle "drop" string per AC spec - TextBlock.text: make optional (some cards omit it) - ProgressBar.value: make optional - ActionStyle: add "other" case - CardAction: add .unknown case for graceful fallback - TargetElement: accept string shorthand - Input.isRequired: decode from string "true"/"false" - AdaptiveCard.body/actions: skip non-array values gracefully - Image.themedUrls: handle array format - Carousel.pages: handle template string expressions - PopoverAction.popoverBody: make optional Repo changes: - Add ios/SampleApp.xcodeproj to git (exception in .gitignore) - Add CardParsingRegressionTests (4 test groups, 634 cards) - Add test scripts: auto-test-ios-cards.sh, test-ios-cards-visual.sh * feat(ios): deep link navigation + visual test loop for automated card testing - Add adaptivecards://card/{path} URL scheme for programmatic navigation - DeepLinkRouter handles URL → card detail view via fullScreenCover - visual-test-loop.sh: automated screenshot capture for all Teams Official cards Uses simctl openurl + simctl io screenshot — no accessibility permissions needed - All 19 Teams Official cards render successfully (visual verification) Remaining minor issues (tracked for future): - Badge element type not yet supported (shows "Unknown element type: Badge") - Some Fluent icon names need additional SF Symbol mappings - Network images (person photos, hero images) depend on connectivity * docs: add sample app deep link testing and visual test loop to CLAUDE.md Documents the adaptivecards:// URL scheme, automated visual test loop, and card parsing regression test commands for developer reference. * feat(testing): add self-healing iOS card test loop command bash shared/scripts/self-heal-ios.sh — full automated test cycle: Phase 1: Parse regression (swift test --filter CardParsingRegressionTests) Phase 2: Visual smoke (deep-link → screenshot → analyze each card) Phase 3: Markdown report with per-card status + screenshots Modes: --parse-only, --visual-only, --card <name> Results: 19/19 Teams Official cards pass (0 failures) * feat(testing): add self-healing test loops for iOS and Android Add automated detect → diagnose → recover → fix test scripts for both platforms. Each runs a 6-phase cycle: parse regression tests, visual smoke tests with deep-link navigation and screenshots, multi-signal crash/hang/OOM diagnosis from simulator logs (iOS) or logcat (Android), auto-retry with escalating recovery, structured fix suggestions with file-level hints, and a rich markdown report with all artifacts. iOS script uses xcrun simctl + system log mining; Android script uses adb + logcat analysis. Both support --parse-only, --visual-only, --card, --retry, and --category flags. * feat(ios,android): rendering fixes, input parity, and sample app improvements Container rendering: - Add showBorder and roundedCorners support to Container model and view on both platforms - Render border stroke using host config borderColor when showBorder is true Image rendering (Android): - Fix Auto-sized images to fill container width per AC spec (fillMaxWidth) - Use FillWidth content scale for aspect-ratio-preserving full-width images - Add RoundedCorners image style enum and 8dp corner radius rendering Input parity (iOS): - Fix DateInputView pre-populating today's date when no value specified - Fix TimeInputView pre-populating current time when no value specified - Both now show placeholder text until user explicitly selects a value - Add required field suffix (* indicator) to all input labels via host config Progress bar (iOS): - Fix named color resolution (green, accent, attention, etc.) in ProgressBarView - Color(hex:) was receiving named strings like "green" and falling back to black Icon mapping (Android): - Map "Crown" icon to WorkspacePremium instead of Star for better visual parity App icon: - Add custom app icon for both iOS (Assets.xcassets) and Android (mipmap resources) - Update AndroidManifest.xml with icon and roundIcon attributes - Add Assets.xcassets to Xcode project build phases Sample app enhancements: - Improved card gallery, detail screens, and Teams simulator on both platforms - Added input renderer setup, bookmarks, settings, and performance dashboard - Enhanced deep link navigation and self-healing test scripts * feat(ios,android): extended deep link routing, gallery filters, cart icon, and demo script Add full deep link navigation support (editor, performance, bookmarks, settings, more) on both platforms with gallery category filtering via adaptivecards://gallery/{filter}. Add cart/cartfilled icon mapping for parity. Include dual-platform demo-bookmarks.sh script for automated bookmark walkthroughs. Update README with latest sample app features and 52 test cards. * docs: Documentation updates with latest changes 3/11 * feat(ios,android): rename sample app to AC Visualizer Rename the sample app from "Adaptive Cards Sample App" to "AC Visualizer" across both platforms, including app display names, hero headers, footer labels, Xcode target/scheme, scripts, and docs. Verified on both iOS and Android simulators. * refactor(ios,android): JSON-driven host config, remove ac-host-config module Replace hardcoded TeamsHostConfig factory methods with JSON files loaded at runtime. This aligns with the Teams-AdaptiveCards-Mobile reference architecture where JSON is the source of truth for host configs. Architecture changes: - Host config JSON source of truth in shared/host-configs/{ios,android}/ - iOS TeamsHostConfig loads from bundled SPM resources (227 → 41 lines) - Android TeamsHostConfig loads from classpath resources (497 → 44 lines) - iOS gains dark theme support (TeamsHostConfig.createDark()) - Remove ac-host-config module, move HostConfigProvider + TeamsTheme into ac-rendering/theme/ — achieves 11/11 module parity - Update 20 Android import paths - Self-heal scripts resize screenshots to 540px for smaller file sizes Verified: dual-platform self-heal test 38/38 pass (19 iOS + 19 Android)
…ikrantSingh01#56) * fix(ios): resolve all card parsing failures + add xcodeproj to repo Self-healing loop: ran CardParsingRegressionTests against 634 cards, found 60+ parsing failures, fixed ALL to 0 failures. Parsing fixes: - CaseInsensitiveCodable: fallback to default instead of throwing (handles template expressions like ${if(...)}) - CompoundButton.icon: accept both string and {name,size,color} object - RichTextBlock.inlines: accept plain strings as TextRun shorthand - CardElement.fallback: handle "drop" string per AC spec - TextBlock.text: make optional (some cards omit it) - ProgressBar.value: make optional - ActionStyle: add "other" case - CardAction: add .unknown case for graceful fallback - TargetElement: accept string shorthand - Input.isRequired: decode from string "true"/"false" - AdaptiveCard.body/actions: skip non-array values gracefully - Image.themedUrls: handle array format - Carousel.pages: handle template string expressions - PopoverAction.popoverBody: make optional Repo changes: - Add ios/SampleApp.xcodeproj to git (exception in .gitignore) - Add CardParsingRegressionTests (4 test groups, 634 cards) - Add test scripts: auto-test-ios-cards.sh, test-ios-cards-visual.sh * feat(ios): deep link navigation + visual test loop for automated card testing - Add adaptivecards://card/{path} URL scheme for programmatic navigation - DeepLinkRouter handles URL → card detail view via fullScreenCover - visual-test-loop.sh: automated screenshot capture for all Teams Official cards Uses simctl openurl + simctl io screenshot — no accessibility permissions needed - All 19 Teams Official cards render successfully (visual verification) Remaining minor issues (tracked for future): - Badge element type not yet supported (shows "Unknown element type: Badge") - Some Fluent icon names need additional SF Symbol mappings - Network images (person photos, hero images) depend on connectivity * docs: add sample app deep link testing and visual test loop to CLAUDE.md Documents the adaptivecards:// URL scheme, automated visual test loop, and card parsing regression test commands for developer reference. * feat(testing): add self-healing iOS card test loop command bash shared/scripts/self-heal-ios.sh — full automated test cycle: Phase 1: Parse regression (swift test --filter CardParsingRegressionTests) Phase 2: Visual smoke (deep-link → screenshot → analyze each card) Phase 3: Markdown report with per-card status + screenshots Modes: --parse-only, --visual-only, --card <name> Results: 19/19 Teams Official cards pass (0 failures) * feat(testing): add self-healing test loops for iOS and Android Add automated detect → diagnose → recover → fix test scripts for both platforms. Each runs a 6-phase cycle: parse regression tests, visual smoke tests with deep-link navigation and screenshots, multi-signal crash/hang/OOM diagnosis from simulator logs (iOS) or logcat (Android), auto-retry with escalating recovery, structured fix suggestions with file-level hints, and a rich markdown report with all artifacts. iOS script uses xcrun simctl + system log mining; Android script uses adb + logcat analysis. Both support --parse-only, --visual-only, --card, --retry, and --category flags. * feat(ios,android): rendering fixes, input parity, and sample app improvements Container rendering: - Add showBorder and roundedCorners support to Container model and view on both platforms - Render border stroke using host config borderColor when showBorder is true Image rendering (Android): - Fix Auto-sized images to fill container width per AC spec (fillMaxWidth) - Use FillWidth content scale for aspect-ratio-preserving full-width images - Add RoundedCorners image style enum and 8dp corner radius rendering Input parity (iOS): - Fix DateInputView pre-populating today's date when no value specified - Fix TimeInputView pre-populating current time when no value specified - Both now show placeholder text until user explicitly selects a value - Add required field suffix (* indicator) to all input labels via host config Progress bar (iOS): - Fix named color resolution (green, accent, attention, etc.) in ProgressBarView - Color(hex:) was receiving named strings like "green" and falling back to black Icon mapping (Android): - Map "Crown" icon to WorkspacePremium instead of Star for better visual parity App icon: - Add custom app icon for both iOS (Assets.xcassets) and Android (mipmap resources) - Update AndroidManifest.xml with icon and roundIcon attributes - Add Assets.xcassets to Xcode project build phases Sample app enhancements: - Improved card gallery, detail screens, and Teams simulator on both platforms - Added input renderer setup, bookmarks, settings, and performance dashboard - Enhanced deep link navigation and self-healing test scripts * feat(ios,android): extended deep link routing, gallery filters, cart icon, and demo script Add full deep link navigation support (editor, performance, bookmarks, settings, more) on both platforms with gallery category filtering via adaptivecards://gallery/{filter}. Add cart/cartfilled icon mapping for parity. Include dual-platform demo-bookmarks.sh script for automated bookmark walkthroughs. Update README with latest sample app features and 52 test cards. * docs: Documentation updates with latest changes 3/11 * feat(ios,android): rename sample app to AC Visualizer Rename the sample app from "Adaptive Cards Sample App" to "AC Visualizer" across both platforms, including app display names, hero headers, footer labels, Xcode target/scheme, scripts, and docs. Verified on both iOS and Android simulators. * refactor(ios,android): JSON-driven host config, remove ac-host-config module Replace hardcoded TeamsHostConfig factory methods with JSON files loaded at runtime. This aligns with the Teams-AdaptiveCards-Mobile reference architecture where JSON is the source of truth for host configs. Architecture changes: - Host config JSON source of truth in shared/host-configs/{ios,android}/ - iOS TeamsHostConfig loads from bundled SPM resources (227 → 41 lines) - Android TeamsHostConfig loads from classpath resources (497 → 44 lines) - iOS gains dark theme support (TeamsHostConfig.createDark()) - Remove ac-host-config module, move HostConfigProvider + TeamsTheme into ac-rendering/theme/ — achieves 11/11 module parity - Update 20 Android import paths - Self-heal scripts resize screenshots to 540px for smaller file sizes Verified: dual-platform self-heal test 38/38 pass (19 iOS + 19 Android) * fix(ios,android): rendering parity fixes, image comparison testing, test card cleanup iOS rendering fixes: - CarouselView: card container with emphasis background, custom accent-colored page indicators, initialPage fix via async dispatch, responsive tablet padding - TableView: apply gridStyle (good/warning/attention) background colors - ChoiceSetInputView: filtered mode renders as typeahead text field instead of radio button list - ImageView: failed images silently collapse (matching Android Coil behavior), unsized images fill available width (matching Android FillWidth) - ForEach ID collisions fixed in CarouselView and TableView using index-based IDs - CarouselPage model now decodes JSON "id" field for unique identification Android rendering fixes: - FactSet spacing reduced from 32dp to 8dp in both light/dark hostConfig JSON and FactSetConfig default, matching Figma design spec Testing improvements: - Dual test script uses pixel-level image comparison (compare-screenshots.py) for PARITY MISMATCH detection instead of file-size heuristic - Report now includes Diff % column showing cross-platform visual similarity - iOS app launch wait increased to 3s to reduce transient crash false positives - Test coverage expanded to include versioned/v1.5 and v1.6 cards Test card cleanup (655 -> 332 files, 49% reduction): - Removed teams-samples/ (100% duplicate of templates/) - Removed consolidated/ (duplicate of element-samples/) - Removed versioned/v1.0-v1.4 (covered by v1.5/v1.6 superset) - Removed 64 versioned/ files duplicating element-samples/ and official-samples/ - Removed 9 internal versioned/ duplicates and near-duplicates - Updated iOS/Android sample app galleries to reference templates/ instead of teams-samples/ - Updated test scripts to reflect cleaned directory structure
…ile parity (VikrantSingh01#57) (VikrantSingh01#57) * feat(shared): OS compat fixes, crash safety, chart parity, pre-commit hook (VikrantSingh01#57) Backward compatibility & build config: - Enable coreLibraryDesugaring for java.time in ac-inputs and sample-app - Align compileSdk=34 across all modules (ac-copilot-extensions, ac-teams were 35) - Add missing targetSdk=34 to ac-templating, ac-copilot-extensions, ac-teams Crash fixes (Android): - AccordionView: snapshot keys with .toList() before iterating (ConcurrentModificationException) - CarouselView: use getOrNull() for page index (IndexOutOfBoundsException) - DataGridInputView: add bounds checks on cell edit and date picker callbacks - StringFunctions.substring: fix boundary case when start == str.length - CodeBlockView: replace Toast with Snackbar, use typed getSystemService() Crash fixes (iOS): - CardAction: remove force unwrap on nil actionTitle - StringFunctions.substring: align boundary case with Android (start == count returns "") - CarouselView: add UIKit import guard for UIScreen in SPM builds Parity fixes: - Wire chart rendering in Android (BarChart, DonutChart, LineChart, PieChart) - Add ac-charts dependency to ac-rendering module - Add Badge and Icon to Android SchemaValidator VALID_ELEMENT_TYPES Pre-commit hook (.githooks/pre-commit): - 35+ rules across Swift (S1-S14), Kotlin (K1-K20), Gradle (G1-G3), JSON (J1-J2), cross-platform parity (P1-P5), and general (A1-A3) - Inline suppression via // safe: or // pre-commit:allow comments - Multi-line detection for remember{mutableStateOf}, @volatile annotations, @Suppress("UNCHECKED_CAST"), and KDoc comment filtering - Install: git config core.hooksPath .githooks * fix(ios,android): ProgressBar max/value normalization, split AdvancedElements into 1:1 files - Add `max` property to ProgressBar model (iOS + Android) for absolute value scales - Add `normalizedValue` computed property: auto-detects 0–1 fractional vs 0–100 scale - Update renderers to use normalizedValue for bar width, percentage text, accessibility - Split Android AdvancedElements.kt monolith into 9 focused files matching iOS structure: Accordion, Carousel, ChartElements, CodeBlock, CompoundButton, ListElement, ProgressElements, RatingElements, TabSet
…01#58) * feat(shared): OS compat fixes, crash safety, chart parity, pre-commit hook (VikrantSingh01#57) Backward compatibility & build config: - Enable coreLibraryDesugaring for java.time in ac-inputs and sample-app - Align compileSdk=34 across all modules (ac-copilot-extensions, ac-teams were 35) - Add missing targetSdk=34 to ac-templating, ac-copilot-extensions, ac-teams Crash fixes (Android): - AccordionView: snapshot keys with .toList() before iterating (ConcurrentModificationException) - CarouselView: use getOrNull() for page index (IndexOutOfBoundsException) - DataGridInputView: add bounds checks on cell edit and date picker callbacks - StringFunctions.substring: fix boundary case when start == str.length - CodeBlockView: replace Toast with Snackbar, use typed getSystemService() Crash fixes (iOS): - CardAction: remove force unwrap on nil actionTitle - StringFunctions.substring: align boundary case with Android (start == count returns "") - CarouselView: add UIKit import guard for UIScreen in SPM builds Parity fixes: - Wire chart rendering in Android (BarChart, DonutChart, LineChart, PieChart) - Add ac-charts dependency to ac-rendering module - Add Badge and Icon to Android SchemaValidator VALID_ELEMENT_TYPES Pre-commit hook (.githooks/pre-commit): - 35+ rules across Swift (S1-S14), Kotlin (K1-K20), Gradle (G1-G3), JSON (J1-J2), cross-platform parity (P1-P5), and general (A1-A3) - Inline suppression via // safe: or // pre-commit:allow comments - Multi-line detection for remember{mutableStateOf}, @volatile annotations, @Suppress("UNCHECKED_CAST"), and KDoc comment filtering - Install: git config core.hooksPath .githooks * fix(ios,android): ProgressBar max/value normalization, split AdvancedElements into 1:1 files - Add `max` property to ProgressBar model (iOS + Android) for absolute value scales - Add `normalizedValue` computed property: auto-detects 0–1 fractional vs 0–100 scale - Update renderers to use normalizedValue for bar width, percentage text, accessibility - Split Android AdvancedElements.kt monolith into 9 focused files matching iOS structure: Accordion, Carousel, ChartElements, CodeBlock, CompoundButton, ListElement, ProgressElements, RatingElements, TabSet * fix(android): resolve 3 serialization crashes affecting 23 cards - CompoundButton.icon: handle both string and object JSON forms via IconDescriptor + IconDescriptorSerializer (10 cards) - Image.themedUrls: gracefully skip JSON arrays in CardElementSerializer pre-processing (2 cards) - RichTextBlock inlines: support plain string shorthand via TextRunSerializer per Adaptive Cards spec (1 card) - iOS: themedUrls array tolerance, ImageView/gallery improvements - self-heal-dual.sh: app-alive wait loops, gallery-baseline retry checks - Rename test card to remove '&' from filename
* fix(ios): resolve all card parsing failures + add xcodeproj to repo
Self-healing loop: ran CardParsingRegressionTests against 634 cards,
found 60+ parsing failures, fixed ALL to 0 failures.
Parsing fixes:
- CaseInsensitiveCodable: fallback to default instead of throwing
(handles template expressions like ${if(...)})
- CompoundButton.icon: accept both string and {name,size,color} object
- RichTextBlock.inlines: accept plain strings as TextRun shorthand
- CardElement.fallback: handle "drop" string per AC spec
- TextBlock.text: make optional (some cards omit it)
- ProgressBar.value: make optional
- ActionStyle: add "other" case
- CardAction: add .unknown case for graceful fallback
- TargetElement: accept string shorthand
- Input.isRequired: decode from string "true"/"false"
- AdaptiveCard.body/actions: skip non-array values gracefully
- Image.themedUrls: handle array format
- Carousel.pages: handle template string expressions
- PopoverAction.popoverBody: make optional
Repo changes:
- Add ios/SampleApp.xcodeproj to git (exception in .gitignore)
- Add CardParsingRegressionTests (4 test groups, 634 cards)
- Add test scripts: auto-test-ios-cards.sh, test-ios-cards-visual.sh
* feat(ios): deep link navigation + visual test loop for automated card testing
- Add adaptivecards://card/{path} URL scheme for programmatic navigation
- DeepLinkRouter handles URL → card detail view via fullScreenCover
- visual-test-loop.sh: automated screenshot capture for all Teams Official cards
Uses simctl openurl + simctl io screenshot — no accessibility permissions needed
- All 19 Teams Official cards render successfully (visual verification)
Remaining minor issues (tracked for future):
- Badge element type not yet supported (shows "Unknown element type: Badge")
- Some Fluent icon names need additional SF Symbol mappings
- Network images (person photos, hero images) depend on connectivity
* docs: add sample app deep link testing and visual test loop to CLAUDE.md
Documents the adaptivecards:// URL scheme, automated visual test loop,
and card parsing regression test commands for developer reference.
* feat(testing): add self-healing iOS card test loop command
bash shared/scripts/self-heal-ios.sh — full automated test cycle:
Phase 1: Parse regression (swift test --filter CardParsingRegressionTests)
Phase 2: Visual smoke (deep-link → screenshot → analyze each card)
Phase 3: Markdown report with per-card status + screenshots
Modes: --parse-only, --visual-only, --card <name>
Results: 19/19 Teams Official cards pass (0 failures)
* feat(testing): add self-healing test loops for iOS and Android
Add automated detect → diagnose → recover → fix test scripts for both
platforms. Each runs a 6-phase cycle: parse regression tests, visual
smoke tests with deep-link navigation and screenshots, multi-signal
crash/hang/OOM diagnosis from simulator logs (iOS) or logcat (Android),
auto-retry with escalating recovery, structured fix suggestions with
file-level hints, and a rich markdown report with all artifacts.
iOS script uses xcrun simctl + system log mining; Android script uses
adb + logcat analysis. Both support --parse-only, --visual-only,
--card, --retry, and --category flags.
* feat(ios,android): rendering fixes, input parity, and sample app improvements
Container rendering:
- Add showBorder and roundedCorners support to Container model and view on both platforms
- Render border stroke using host config borderColor when showBorder is true
Image rendering (Android):
- Fix Auto-sized images to fill container width per AC spec (fillMaxWidth)
- Use FillWidth content scale for aspect-ratio-preserving full-width images
- Add RoundedCorners image style enum and 8dp corner radius rendering
Input parity (iOS):
- Fix DateInputView pre-populating today's date when no value specified
- Fix TimeInputView pre-populating current time when no value specified
- Both now show placeholder text until user explicitly selects a value
- Add required field suffix (* indicator) to all input labels via host config
Progress bar (iOS):
- Fix named color resolution (green, accent, attention, etc.) in ProgressBarView
- Color(hex:) was receiving named strings like "green" and falling back to black
Icon mapping (Android):
- Map "Crown" icon to WorkspacePremium instead of Star for better visual parity
App icon:
- Add custom app icon for both iOS (Assets.xcassets) and Android (mipmap resources)
- Update AndroidManifest.xml with icon and roundIcon attributes
- Add Assets.xcassets to Xcode project build phases
Sample app enhancements:
- Improved card gallery, detail screens, and Teams simulator on both platforms
- Added input renderer setup, bookmarks, settings, and performance dashboard
- Enhanced deep link navigation and self-healing test scripts
* feat(ios,android): extended deep link routing, gallery filters, cart icon, and demo script
Add full deep link navigation support (editor, performance, bookmarks, settings, more) on
both platforms with gallery category filtering via adaptivecards://gallery/{filter}. Add
cart/cartfilled icon mapping for parity. Include dual-platform demo-bookmarks.sh script for
automated bookmark walkthroughs. Update README with latest sample app features and 52 test cards.
* docs: Documentation updates with latest changes 3/11
* feat(ios,android): rename sample app to AC Visualizer
Rename the sample app from "Adaptive Cards Sample App" to
"AC Visualizer" across both platforms, including app display names,
hero headers, footer labels, Xcode target/scheme, scripts, and docs.
Verified on both iOS and Android simulators.
* refactor(ios,android): JSON-driven host config, remove ac-host-config module
Replace hardcoded TeamsHostConfig factory methods with JSON files loaded
at runtime. This aligns with the Teams-AdaptiveCards-Mobile reference
architecture where JSON is the source of truth for host configs.
Architecture changes:
- Host config JSON source of truth in shared/host-configs/{ios,android}/
- iOS TeamsHostConfig loads from bundled SPM resources (227 → 41 lines)
- Android TeamsHostConfig loads from classpath resources (497 → 44 lines)
- iOS gains dark theme support (TeamsHostConfig.createDark())
- Remove ac-host-config module, move HostConfigProvider + TeamsTheme
into ac-rendering/theme/ — achieves 11/11 module parity
- Update 20 Android import paths
- Self-heal scripts resize screenshots to 540px for smaller file sizes
Verified: dual-platform self-heal test 38/38 pass (19 iOS + 19 Android)
* fix(ios,android): rendering parity fixes, image comparison testing, test card cleanup
iOS rendering fixes:
- CarouselView: card container with emphasis background, custom accent-colored
page indicators, initialPage fix via async dispatch, responsive tablet padding
- TableView: apply gridStyle (good/warning/attention) background colors
- ChoiceSetInputView: filtered mode renders as typeahead text field instead of
radio button list
- ImageView: failed images silently collapse (matching Android Coil behavior),
unsized images fill available width (matching Android FillWidth)
- ForEach ID collisions fixed in CarouselView and TableView using index-based IDs
- CarouselPage model now decodes JSON "id" field for unique identification
Android rendering fixes:
- FactSet spacing reduced from 32dp to 8dp in both light/dark hostConfig JSON
and FactSetConfig default, matching Figma design spec
Testing improvements:
- Dual test script uses pixel-level image comparison (compare-screenshots.py)
for PARITY MISMATCH detection instead of file-size heuristic
- Report now includes Diff % column showing cross-platform visual similarity
- iOS app launch wait increased to 3s to reduce transient crash false positives
- Test coverage expanded to include versioned/v1.5 and v1.6 cards
Test card cleanup (655 -> 332 files, 49% reduction):
- Removed teams-samples/ (100% duplicate of templates/)
- Removed consolidated/ (duplicate of element-samples/)
- Removed versioned/v1.0-v1.4 (covered by v1.5/v1.6 superset)
- Removed 64 versioned/ files duplicating element-samples/ and official-samples/
- Removed 9 internal versioned/ duplicates and near-duplicates
- Updated iOS/Android sample app galleries to reference templates/ instead of
teams-samples/
- Updated test scripts to reflect cleaned directory structure
…ut.DataGrid, and rendering parity fixes Cross-platform parity update adding new action types (Action.Popover, Action.RunCommands, Action.OpenUrlDialog), Input.DataGrid element, and rendering improvements across ImageView, RichTextBlockView, CompoundButtonView, ActionSetView, TableView, and TemplateEngine on both platforms. Updates schema validators, test cards, and parity matrix.
…ut.DataGrid, and rendering parity fixes (VikrantSingh01#60) Cross-platform parity update adding new action types (Action.Popover, Action.RunCommands, Action.OpenUrlDialog), Input.DataGrid element, and rendering improvements across ImageView, RichTextBlockView, CompoundButtonView, ActionSetView, TableView, and TemplateEngine on both platforms. Updates schema validators, test cards, and parity matrix.
…sing - Action.Popover: generate fallback ID when action has no id field, fixing popover not opening on Android (iOS already had this) - Icon resolution: strip ",Filled"/",Regular" style suffix from icon:Name,Style format before lookup on both platforms - Add ArrowReset and ToggleLeft icon mappings on both platforms
- Use firstOrNull() instead of first() in icon suffix stripping to avoid potential exception on empty strings (K5 warning) - Apply same icon suffix stripping fix to ac-actions ActionButton.kt (duplicate resolver that was also missing the ,Filled handling) - Add ArrowReset and ToggleLeft mappings to ac-actions icon table
… icon mappings (VikrantSingh01#61) - Action.Popover: generate fallback ID ("popover_{title}") when action has no id field — fixes popover not opening on Android - Icon resolution: strip ",Filled"/",Regular" style suffix from "icon:Name,Style" format before lookup on all 3 icon resolvers (iOS ActionButton, Android ac-rendering, Android ac-actions) - Add ArrowReset and ToggleLeft icon mappings on both platforms - Use firstOrNull() for safe icon suffix splitting on Android
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…legate wiring - Add action-test-loop.sh for dual-platform E2E action card testing (25 cards) - Fix Android ActionSetView overflow: replace Row with FlowRow so buttons wrap to next line instead of being squeezed with vertical text - Wire ActionDelegate/LoggingActionHandler in both sample apps for action logging - Add edge-action-crashes.json test card and ACActionsTests - Register action-overflow and edge-action-crashes in both card loaders - Screenshot-based pass/fail validation (no false crash detection)
…links
Add action-invoke-test.sh that navigates to action cards, programmatically
triggers every action button, and verifies no crash + correct UX response.
Both platforms now support adaptivecards://tap-action/{title} deep links
that trigger card actions by title, enabling reliable test automation
without fragile coordinate-based UI tapping.
iOS: AdaptiveCardView accepts pendingActionTitle binding, finds the action
by title in the parsed card, and invokes it via ActionHandler with full
CardViewModel access (ShowCard, Popover, ToggleVisibility all work).
Android: Same approach via MutableState<String?> parameter plumbed from
MainActivity → CardDetailScreen → AdaptiveCardView. handleAction and
collectAllActionsForCard made public for cross-module access.
Script features:
- Dual-platform (iOS + Android) action invocation testing
- JSON parsing to extract all actions (card-level + body ActionSets)
- Android: uiautomator dump with Compose parent-traversal for button
finding, overflow menu handling, fd-based loop to prevent stdin
consumption by child processes
- iOS: deep link approach (100% reliable vs coordinate estimation)
- Pre/post screenshot comparison for visual action UX verification
- Visual actions (ShowCard, ToggleVisibility, Popover) must change screen
Update README files to reference ACVisualizer (correct scheme name) instead of outdated AdaptiveCardsSample. Increase demo-bookmarks.sh wait times for performance dashboard and more page.
Adds the standard 3-line copyright header to all 319 source files: Swift, Kotlin, shell scripts, Python scripts, YAML CI workflows, and the pre-commit hook.
Moved video to a published GitHub release asset (MP4 format) and use a bare URL in README so GitHub renders it as an inline player. Removed the 26MB .mov from the repo tree.
Show an inline poster image extracted from the demo video. Clicking the thumbnail downloads the full MP4 from GitHub Releases.
…erlap The markdown renderer used absolute SwiftUI semantic fonts (.title, .title2, .title3) for header tokens, ignoring the TextBlock's configured font size. This caused the header text to be much larger than the allocated space, resulting in overlapping text artifacts. Now uses the base font with bold applied, matching the TextBlock's own size/weight properties. Aligns with Android's approach of respecting the base font. Issue VikrantSingh01#6, VikrantSingh01#20
…ncation Long cards with multiple ActionSets (e.g., ActionModeTestCard) were truncated because the card body VStack was clipped without scrolling. Android uses verticalScroll() for internal scrolling. Now wraps the card body in ScrollView to match Android behavior, allowing all content to be accessible via scrolling. Issue VikrantSingh01#9
…Flow navigation Navigation Compose 2.7.x route matching fails for filenames with multiple dots (e.g. Container.Nested.Flow.json). Uri.encode leaves dots unencoded since they are RFC 3986 unreserved characters, but the dots confuse Navigation's internal route matching. Manually encoding dots as %2E prevents this while Uri.decode on the receive side correctly decodes them.
…lView The DataGrid only showed the header row because a nested ScrollView(.vertical) inside ScrollView(.horizontal) caused the inner scroll view to render with zero height. Removed the inner vertical ScrollView and render data rows directly in the VStack, matching Android's approach. The card-level ScrollView handles overflow. Issue VikrantSingh01#10
…P 403 Servers like Wikipedia block requests without a proper User-Agent header, causing Coil to silently fail with HTTP 403. This made the hero image invisible in the InputForm card (and potentially other cards with images from strict servers). Issue VikrantSingh01#3: Hero image (skier) missing from Android InputForm
The project-dashboard card uses AreaGrid with columns: [50] but areas referencing column 2. Android's AreaGridLayoutView used columns.size for columnCount (=1), giving column 2 a minimal weight of 1 vs 50, squeezing content to ~2% width and pushing everything below off-screen. iOS correctly uses max(columns.count, maxAreaColumn) to infer the actual column count. This fix preprocesses the AreaGridLayout in ContainerView to expand the columns list when areas reference columns beyond the defined range, distributing remaining width equally to missing columns. Fixes truncation of ~70% of content in deeply nested cards like teams-official-samples/project-dashboard.
Action button icons loaded via AsyncImage in ActionSetView were using plain URL strings without User-Agent headers, causing HTTP 403 from servers like Wikipedia that require proper User-Agent. Now builds a proper ImageRequest with User-Agent header, matching the fix in ImageView. Issue VikrantSingh01#8: Android action button icons missing for themed URLs
… columns Images with height="auto" and width="auto" (no fitMode) were always constrained to a 52x52dp square, making them tiny compared to iOS which renders them at natural size filling the container width. Now only applies the medium-size constraint in auto-width columns where it prevents layout expansion; in other contexts, fills available width matching iOS behavior. Issue VikrantSingh01#12: Different number of image examples visible between platforms
Align chevron to fixed 20pt size with 0.6 opacity (matching Android 20dp) instead of font-based sizing. Increase minHeight from 44 to 48 to match Android, improving intrinsic size parity for flow layout wrapping. Issue VikrantSingh01#8: CompoundButton chevron/icon parity
Standalone clickable icons (direct children of card body) were centered on iOS due to no frame being applied when horizontalAlignment was nil. Android naturally left-aligns icons in a Column. Now iOS always applies frame with maxWidth .infinity and leading alignment by default. Issue VikrantSingh01#10
Android AdaptiveCardView had verticalScroll on the inner Column, which conflicted with the sample app scrollable parent container (nested scroll issue). This caused content to be clipped after Action 4 on long cards like ActionModeTestCard. Removed inner verticalScroll to let the card expand to intrinsic content height, matching iOS pattern where the parent handles scrolling. Issue VikrantSingh01#11
Remove the 1/3 width cap in ActionFlowLayout that was truncating long button labels like 'Invalid icon does not render'. Now matches Android FlowRow behavior where buttons take natural width and wrap to next row. Individual buttons are still capped to available width to prevent overflow. Issue VikrantSingh01#15: Button text truncated on iOS but fully visible on Android
…nd icon Action.ResetInputs was falling to .unknown(type:) case which has no title/iconUrl properties, causing buttons to render as empty unlabeled squares. Added ResetInputsAction struct with full base action properties and targetInputIds support.
The User-Agent header added in 2530dee was lost during a merge/rebase. Servers like Wikipedia block requests without a proper User-Agent header (HTTP 403), causing the scuba diver image to be invisible in the input-form-official card. Issue VikrantSingh01#5: Android missing scuba diver column image in input form cards
…r rendering Individual images in an ImageSet had no size property, causing ImageView to use nil width/height and render a 0x0 placeholder. Now copies the ImageSet imageSize onto each image before rendering, matching Android behavior.
…h iOS Android was using Modifier.size() for Small/Medium/Large images, which constrains both width AND height to the same value (e.g., 52x52 for Medium). This caused portrait-oriented images to render ~20-30% smaller than iOS, which only constrains width and lets height be proportional. Changed to Modifier.width() for all named sizes to match iOS behavior. Issue VikrantSingh01#14: Force-load images render smaller on Android than iOS
Added mappings for Calendar, ImageCircle, Important, Tag, TooltipQuote, ArrowSync, Checkmark, People, Megaphone, Receipt, Cart, Design to Material Icons. Previously these all rendered as the generic Label placeholder.
When isMultiSelect is true and style is compact, iOS was rendering inline checkboxes (expanded-like). Android renders this as a compact dropdown picker. Changed iOS multiSelectCompactView to use a Menu dropdown matching Android behavior, with a summary of selected items shown in the collapsed state. Issue VikrantSingh01#9
# Conflicts: # android/ac-rendering/src/main/kotlin/com/microsoft/adaptivecards/rendering/composables/BadgeView.kt
…overflow CardDetailScreen: add fallback lookup for .template.json files when deep link resolves to .json — fixes templates/WeatherLarge and other template cards showing "Empty JSON string". ImageView: remove heightIn(min:) from Stretch sizing and use FillWidth content scale instead of Crop — prevents weather icon images from growing unbounded in weighted columns.
Cards were vertically centered in the detail view due to SwiftUI default frame alignment. Short cards appeared floating in the middle of the screen. Added alignment: .topLeading to pin content to the top.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Description
This changes the alpha on the line numbers in the code block card type and refactors and improves the Compound Button card to be closer to web implementation.
Known issues: I haven't been able to run the tests yet because of a gradle dependency issue. Working on that now.
Screenshots attached below.
Type of Change
Cross-Platform Parity Checklist
For all code changes affecting card rendering or schema support:
shared/test-cards/(if applicable)Impact & Regression Testing (MANDATORY — Zero Regressions Policy)
Every impacted card, flow, and scenario MUST be tested before merge.
Impact Analysis
Impacted modules:
Impacted card types:
Impacted flows:
Regression Test Results
swift test(iOS) and./gradlew test(Android) passswift test --filter CardParsingRegressionTestspassescheck-screenshot-text.shon all screenshots — no unresolved templates or error textcompare-schema-coverage.shpasses (if element/action types changed)test-template-cards-dual.shpasses (if templating changed)shared/scripts/pre-merge-validation.shpassesCards Tested
Testing Checklist
swift test(iOS) and./gradlew test(Android) pass locallySchema Validation (for schema changes)
shared/schema/adaptive-card-schema-1.6.jsonupdated (if applicable)Documentation
Accessibility
Performance
Security
Breaking Changes
Screenshots / Videos
Before:

After:
Related Issues
Additional Notes
Reviewer Checklist
For Maintainers: