Skip to content

feat: let the host set the sheet background and badge the address field - #11

Open
romchornyi wants to merge 3 commits into
masterfrom
feat/bottom-sheet-background
Open

feat: let the host set the sheet background and badge the address field#11
romchornyi wants to merge 3 commits into
masterfrom
feat/bottom-sheet-background

Conversation

@romchornyi

@romchornyi romchornyi commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Issue being fixed or feature implemented

Two components could not be adapted by their hosts without forking them.

BottomSheet hard-coded Color.dash.primaryBackground in three places, so a
sheet that belongs on a different surface had no way to say so. Restyling only
the content is not enough: the background is also what the presentation detent
paints behind the home-indicator inset, so a host that overrode its own content
still got a strip of the original colour along the bottom edge.

AddressFieldView had nowhere to put anything beside its label. The consumer
in dashwallet-ios needs a badge there naming what an entered address decoded to
— a property of the field, not an action on it.

What was done?

BottomSheet takes a background: Color, defaulting to
.dash.primaryBackground so every existing call site renders exactly as
before. It is applied to the sheet body, to both content branches, and to the
presentation background, so the bottom-edge strip cannot reappear.

AddressFieldView became generic over an Accessory view placed opposite the
label, with a Spacer between them. Callers that want none keep the shape they
already had: a constrained extension on Accessory == EmptyView supplies the
old initializer verbatim, so no existing call site changes.

Its Layout constants moved out of the type to file scope. A generic type
cannot hold static stored properties — worth knowing that SwiftPM compiled the
nested version anyway and only Xcode rejected it, so swift build alone does
not prove this file.

How Has This Been Tested?

swift build clean, plus a full dashpay build in dashwallet-ios pinned to
this branch — that consumer is the one exercising both new parameters, and it
is the build that catches what SwiftPM misses. Exercised on the simulator: the
address step with the destination badge, and the sheets that pass a background.

Existing call sites were not touched, and both defaults reproduce the previous
rendering.

Breaking Changes

None at call sites — both additions are defaulted, and the EmptyView
extension keeps AddressFieldView's original initializer.

Worth flagging for anyone writing the type name explicitly: AddressFieldView
is now generic, so an explicit annotation needs a parameter
(AddressFieldView<EmptyView>). Inferred usage is unaffected.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

Summary by CodeRabbit

  • New Features

    • Added optional accessory views to address field labels, such as badges or status indicators.
    • Added configurable background colors for bottom sheets and self-sizing sheets.
    • Bottom sheet backgrounds now extend through the presentation area, including the home-indicator region.
  • Documentation

    • Updated bottom sheet examples and guidance to cover custom presentation backgrounds.

jeanpierreroma and others added 3 commits August 10, 2026 18:17
The fill was hardcoded to `primaryBackground` in five places, and the
presentation background — the one that covers the home-indicator inset —
was only applied when a `cornerRadius` happened to be passed. A host that
wanted anything else had two bad options: restyle its own content and
live with a pale strip along the bottom edge, or pass a corner radius it
did not want purely for the side effect.

`background` is now a parameter on `BottomSheet`, on the `selfSizing`
factory and on `selfSizingSheet(…)`, defaulting to what it was. The
presentation fill applies on iOS 16.4+ regardless of corner radius, so
the strip matches whatever the sheet is filled with.

Why the strip exists at all: the natural-height path deliberately measures
without the bottom safe area, and `presentationDetents([.height])` adds
that inset back — so it lies outside the sheet's own stack and needs the
presentation background to be covered.
The label row was a bare Text, so a host with something to say about the
address it decoded — which chain it turned out to belong to — had nowhere to
put it and had to draw its own label row above the field, printing the label
twice.

An optional accessory sits opposite the label. It is deliberately not inside
the field: the controls in there act on the address (paste, scan, clear),
while this describes it.

Generic over the accessory with an EmptyView convenience initializer, the same
shape NavigationBar uses, so existing callers are untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A generic type cannot hold static stored properties, so the nested Layout enum
stopped compiling the moment the view gained its accessory parameter. SwiftPM
accepted it; Xcode did not, which is where it surfaced.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

AddressFieldView now supports trailing label accessories while preserving its original initializer. BottomSheet now accepts and propagates a configurable background color through fixed-height and self-sizing presentations. Previews and documentation show the new configurations.

Changes

UI component enhancements

Layer / File(s) Summary
AddressFieldView label accessory
Sources/DashUIKit/Components/AddressFieldView.swift
AddressFieldView is generic over an accessory view and displays it beside the label. An EmptyView specialization preserves the existing initializer shape.
BottomSheet background propagation
Sources/DashUIKit/Components/BottomSheet.swift, docs/navigation-and-containers.md
BottomSheet, selfSizing, and selfSizingSheet accept a background color. The color applies to sheet content and presentation backgrounds. Previews and documentation show the configuration.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant BottomSheet
  participant SelfSizingSheet
  participant Presentation
  Caller->>BottomSheet: Provide background color
  BottomSheet->>SelfSizingSheet: Propagate background
  SelfSizingSheet->>Presentation: Apply presentation background
Loading

Possibly related PRs

Suggested reviewers: jeanpierreroma

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes both main changes: configurable sheet backgrounds and an accessory badge for the address field.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bottom-sheet-background

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/DashUIKit/Components/BottomSheet.swift (1)

190-210: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Restrict the presentation-background guarantee to iOS 16.4 and later.

presentationDetents supports iOS 16.0, but presentationBackground supports iOS 16.4 and later. On iOS 16.0–16.3, selfSizingSheet does not fill the presentation’s bottom safe-area strip. Update the source documentation and the two statements in docs/navigation-and-containers.md, or add a UIKit fallback. The existing no-op path below iOS 16 satisfies the iOS 14 fallback requirement.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/BottomSheet.swift` around lines 190 - 210,
Restrict the presentation-background guarantee to iOS 16.4 and later: update the
selfSizingSheet documentation in Sources/DashUIKit/Components/BottomSheet.swift
and both affected statements in docs/navigation-and-containers.md at lines 98
and 112-116 to state that iOS 16.0–16.3 do not fill the bottom safe-area strip,
while preserving the existing no-op behavior below iOS 16; no direct code change
is required in the shown modifier branch unless adding a UIKit fallback instead.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/DashUIKit/Components/AddressFieldView.swift`:
- Around line 341-365: Wrap the iOS 17/macOS 14 `#Preview("Label accessory")`
declaration in `#if DEBUG` and `#endif`, preserving the existing preview
implementation unchanged.
- Around line 352-353: Replace the direct Image(systemName:) badge icon in
AddressFieldView with an appropriate DashIconSource, then render that source
using Image(dash: source) while preserving the existing size and weight styling.
- Around line 343-356: Localize the preview’s user-facing strings in
AddressFieldView by wrapping “Address,” “Dash address,” and “Transparent
address” with NSLocalizedString using bundle: .module and appropriate comments;
add matching entries to the module’s localization resources.
- Around line 31-32: Restore compatibility in AddressFieldView by isolating the
`@FocusState-dependent` behavior and text-field branches behind iOS 15/macOS 12
availability, and provide an equivalent iOS 14/macOS 11 fallback. Then update
AddressFieldView and its compatibility initializer availability to iOS 14/macOS
11 while preserving focus behavior on newer platforms.

In `@Sources/DashUIKit/Components/BottomSheet.swift`:
- Around line 179-188: The selfSizingSheet modifier’s default background must
match the enclosing BottomSheet background. Update the BottomSheet and
selfSizingSheet flow to propagate and reuse the configured sheet color via the
existing environment mechanism, or require the modifier caller to provide it
explicitly; remove the incorrect independent .dash.primaryBackground default and
preserve matching content and presentation colors.
- Around line 305-326: Wrap the `#Preview` declaration for “BottomSheet Custom
Background” in `#if` DEBUG and a matching `#endif`, preserving its existing iOS
17/macOS 14 availability and preview content.
- Around line 190-206: Update the macOS path in the availability-gated modifier
flow around SelfSizingSheetModifier so presentationBackground(background) is
applied on macOS 13.3 and later. Keep the existing iOS-specific corner-radius
handling intact, and ensure older macOS versions continue using the fallback
behavior.

---

Outside diff comments:
In `@Sources/DashUIKit/Components/BottomSheet.swift`:
- Around line 190-210: Restrict the presentation-background guarantee to iOS
16.4 and later: update the selfSizingSheet documentation in
Sources/DashUIKit/Components/BottomSheet.swift and both affected statements in
docs/navigation-and-containers.md at lines 98 and 112-116 to state that iOS
16.0–16.3 do not fill the bottom safe-area strip, while preserving the existing
no-op behavior below iOS 16; no direct code change is required in the shown
modifier branch unless adding a UIKit fallback instead.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 53993a54-173b-43e7-968e-c6816a0d573d

📥 Commits

Reviewing files that changed from the base of the PR and between 88bf41f and d8dff73.

📒 Files selected for processing (3)
  • Sources/DashUIKit/Components/AddressFieldView.swift
  • Sources/DashUIKit/Components/BottomSheet.swift
  • docs/navigation-and-containers.md

Comment on lines 31 to +32
@available(iOS 15, macOS 12, *)
public struct AddressFieldView: View {

private enum Layout {
static let hSpacing: CGFloat = 20
static let lPadding: CGFloat = 20
static let tPadding: CGFloat = 10
static let iconSize: CGFloat = 17
static let cornerRadius: CGFloat = 16
static let actionTapArea: CGFloat = 40
}
public struct AddressFieldView<Accessory: View>: View {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Inspect iOS-specific APIs that must be isolated or replaced for the iOS 14 path.
rg -n -C 3 '`@available`\(iOS|`@FocusState`|`#available`\(iOS|textInputAutocapitalization|disableAutocorrection' \
  Sources/DashUIKit/Components/AddressFieldView.swift

# Inspect declared deployment targets when project metadata is present.
for file in $(fd -HI -t f '^(Package\.swift|project\.pbxproj|.*\.podspec)$' . || true); do
  rg -n -C 2 'iOS|IPHONEOS_DEPLOYMENT_TARGET|platforms|macOS' "$file" || true
done

Repository: dashpay/DashUIKit

Length of output: 3522


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Map and inspect the component and nearby availability-sensitive declarations.
ast-grep outline Sources/DashUIKit/Components/AddressFieldView.swift
sed -n '1,210p' Sources/DashUIKit/Components/AddressFieldView.swift
sed -n '240,370p' Sources/DashUIKit/Components/AddressFieldView.swift

# Check the package deployment declaration and related availability patterns.
rg -n -C 3 'platforms:|\.iOS\(|\.macOS\(|`@FocusState`|focused\(' Package.swift Sources/DashUIKit

Repository: dashpay/DashUIKit

Length of output: 14889


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

path = Path("Sources/DashUIKit/Components/AddressFieldView.swift")
text = path.read_text()

public_annotations = re.findall(
    r'`@available`\(([^)]*)\)\s*(?:public\s+)?(?:struct|extension)\s+AddressFieldView',
    text,
)
focus_declarations = re.findall(r'^\s*`@FocusState`\b.*$', text, re.MULTILINE)
focus_uses = re.findall(r'\.focused\(\$isTextFieldFocused\)', text)
package = Path("Package.swift").read_text()

print("public AddressFieldView availability:")
for annotation in public_annotations:
    print(annotation)
print("FocusState declarations:", len(focus_declarations))
print("focused uses:", len(focus_uses))
print("package iOS 14:", bool(re.search(r'\.iOS\(\.v14\)', package)))
print("focus-dependent computed properties:")
for line_no, line in enumerate(text.splitlines(), 1):
    if "isTextFieldFocused" in line or "isFocusedState" in line:
        print(f"{line_no}: {line.strip()}")
PY

Repository: dashpay/DashUIKit

Length of output: 768


Restore iOS 14 and macOS 11 support for the public API.

Package.swift declares iOS 14 support, but AddressFieldView and its compatibility initializer require iOS 15 and macOS 12. The type also uses @FocusState in its focus-dependent state and both text-field branches. Isolate this behavior and provide an iOS 14 fallback before changing the public declarations to @available(iOS 14, macOS 11, *).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/AddressFieldView.swift` around lines 31 - 32,
Restore compatibility in AddressFieldView by isolating the `@FocusState-dependent`
behavior and text-field branches behind iOS 15/macOS 12 availability, and
provide an equivalent iOS 14/macOS 11 fallback. Then update AddressFieldView and
its compatibility initializer availability to iOS 14/macOS 11 while preserving
focus behavior on newer platforms.

Source: Coding guidelines

Comment on lines +341 to +365
@available(iOS 17, macOS 14, *)
#Preview("Label accessory") {
AddressFieldView(
text: .constant("yV1D1ivvSUyKPJnbFmzSTVh1MyZ3JbeVkY"),
label: "Address",
placeholder: "Dash address",
hasError: false
) {
// What the host puts here is its own: a badge naming the kind of
// address that was entered, decided by the host's own decoder.
HStack(spacing: 4) {
Image(systemName: "d.circle.fill")
.font(.system(size: 10, weight: .semibold))
Text("Transparent address")
.dashFont(.caption2)
}
.foregroundStyle(Color.dash.blueText)
.padding(.horizontal, 8)
.padding(.vertical, 3)
.background(Color.dash.blueAlpha10)
.clipShape(Capsule())
}
.padding()
.background(Color.dash.primaryBackground)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Guard the iOS 17 preview with #if DEBUG.

The new #Preview uses an iOS 17-only declaration without the required debug guard. Wrap Lines 341-365 in #if DEBUG and #endif.

As per coding guidelines, preview-only code may require iOS 17 only when guarded by #if DEBUG.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/AddressFieldView.swift` around lines 341 - 365,
Wrap the iOS 17/macOS 14 `#Preview("Label accessory")` declaration in `#if
DEBUG` and `#endif`, preserving the existing preview implementation unchanged.

Source: Coding guidelines

Comment on lines +343 to +356
AddressFieldView(
text: .constant("yV1D1ivvSUyKPJnbFmzSTVh1MyZ3JbeVkY"),
label: "Address",
placeholder: "Dash address",
hasError: false
) {
// What the host puts here is its own: a badge naming the kind of
// address that was entered, decided by the host's own decoder.
HStack(spacing: 4) {
Image(systemName: "d.circle.fill")
.font(.system(size: 10, weight: .semibold))
Text("Transparent address")
.dashFont(.caption2)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Localize the preview strings.

"Address", "Dash address", and "Transparent address" are user-facing strings. Use NSLocalizedString(_, bundle: .module, comment:) for each string and add the corresponding localized entries.

Proposed change
-        label: "Address",
-        placeholder: "Dash address",
+        label: NSLocalizedString("Address", bundle: .module, comment: "DashUIKit"),
+        placeholder: NSLocalizedString("Dash address", bundle: .module, comment: "DashUIKit"),
...
-            Text("Transparent address")
+            Text(NSLocalizedString("Transparent address", bundle: .module, comment: "DashUIKit"))

As per coding guidelines, localize all user-facing strings with NSLocalizedString(_, bundle: .module, comment:).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
AddressFieldView(
text: .constant("yV1D1ivvSUyKPJnbFmzSTVh1MyZ3JbeVkY"),
label: "Address",
placeholder: "Dash address",
hasError: false
) {
// What the host puts here is its own: a badge naming the kind of
// address that was entered, decided by the host's own decoder.
HStack(spacing: 4) {
Image(systemName: "d.circle.fill")
.font(.system(size: 10, weight: .semibold))
Text("Transparent address")
.dashFont(.caption2)
}
AddressFieldView(
text: .constant("yV1D1ivvSUyKPJnbFmzSTVh1MyZ3JbeVk"),
label: NSLocalizedString("Address", bundle: .module, comment: "DashUIKit"),
placeholder: NSLocalizedString("Dash address", bundle: .module, comment: "DashUIKit"),
hasError: false
) {
// What the host puts here is its own: a badge naming the kind of
// address that was entered, decided by the host's own decoder.
HStack(spacing: 4) {
Image(systemName: "d.circle.fill")
.font(.system(size: 10, weight: .semibold))
Text(NSLocalizedString("Transparent address", bundle: .module, comment: "DashUIKit"))
.dashFont(.caption2)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/AddressFieldView.swift` around lines 343 - 356,
Localize the preview’s user-facing strings in AddressFieldView by wrapping
“Address,” “Dash address,” and “Transparent address” with NSLocalizedString
using bundle: .module and appropriate comments; add matching entries to the
module’s localization resources.

Source: Coding guidelines

Comment on lines +352 to +353
Image(systemName: "d.circle.fill")
.font(.system(size: 10, weight: .semibold))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use a DashIconSource for the badge icon.

Image(systemName:) bypasses the DashUIKit icon source contract. Select or add an appropriate DashIconSource, then render it with Image(dash: source).

As per coding guidelines, represent icons with DashIconSource and render them using Image(dash: source).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/AddressFieldView.swift` around lines 352 - 353,
Replace the direct Image(systemName:) badge icon in AddressFieldView with an
appropriate DashIconSource, then render that source using Image(dash: source)
while preserving the existing size and weight styling.

Source: Coding guidelines

Comment on lines +179 to 188
/// - background: Fill for the sheet and its presentation, so the bottom
/// safe-area strip matches the content. Defaults to the sheet's own.
/// - cornerRadius: Optional corner radius applied via `presentationCornerRadius` on
/// iOS 16.4..<26 (iOS 26+ keeps the system corner styling). When provided, the sheet
/// background is also filled so the bottom safe-area strip matches the content.
/// iOS 16.4..<26 (iOS 26+ keeps the system corner styling).
@ViewBuilder
func selfSizingSheet(
fallback: CGFloat = 0,
maxHeightFraction: CGFloat = 0.95,
background: Color = .dash.primaryBackground,
cornerRadius: CGFloat? = nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Make the direct modifier default match the wrapped sheet.

selfSizingSheet(background:) defaults to .dash.primaryBackground independently of BottomSheet.background. A direct composition with a custom BottomSheet(background:) and .selfSizingSheet() therefore uses different colors for the content and presentation. The bottom inset can show the primary background again.

Propagate the sheet color through an environment value, or remove “Defaults to the sheet’s own” and require direct modifier calls to pass the same color.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/BottomSheet.swift` around lines 179 - 188, The
selfSizingSheet modifier’s default background must match the enclosing
BottomSheet background. Update the BottomSheet and selfSizingSheet flow to
propagate and reuse the configured sheet color via the existing environment
mechanism, or require the modifier caller to provide it explicitly; remove the
incorrect independent .dash.primaryBackground default and preserve matching
content and presentation colors.

Comment on lines 190 to +206
if #available(iOS 16.0, macOS 13.0, *) {
let modified = modifier(SelfSizingSheetModifier(fallback: fallback, maxHeightFraction: maxHeightFraction))
#if os(iOS)
if #available(iOS 16.4, *), let cornerRadius {
if #unavailable(iOS 26.0) {
// iOS 16.4..<26: apply the custom corner radius + fill the sheet background.
if #available(iOS 16.4, *) {
// The background is filled whatever the corner radius: the
// measured height excludes the home-indicator inset that
// `.presentationDetents([.height])` adds back, so that strip
// sits outside the sheet's own `VStack` and shows the system
// background unless this fills it.
if #unavailable(iOS 26.0), let cornerRadius {
modified
.presentationCornerRadius(cornerRadius)
.presentationBackground(Color.dash.primaryBackground)
.presentationBackground(background)
} else {
// iOS 26+: keep the system corner styling, just fill the background.
// iOS 26+ keeps the system corner styling.
modified
.presentationBackground(Color.dash.primaryBackground)
.presentationBackground(background)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="Sources/DashUIKit/Components/BottomSheet.swift"
rg -n -C 6 'presentationBackground|`#if` os\(iOS\)|macOS 13\.0|`@available`\(iOS 14' "$file"

Repository: dashpay/DashUIKit

Length of output: 4155


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- BottomSheet.swift ---'
sed -n '130,240p' Sources/DashUIKit/Components/BottomSheet.swift
printf '%s\n' '--- Package manifests and platform declarations ---'
fd -i -t f 'Package.swift|.*\.podspec|.*\.yml|.*\.yaml' . -x sh -c 'printf "\n--- %s ---\n" "$1"; rg -n -C 3 "platform|macOS|iOS|swift-tools-version" "$1"' sh {}
printf '%s\n' '--- selfSizingSheet usages ---'
rg -n -C 3 'selfSizingSheet|BottomSheet\.selfSizing|BottomSheet\(' Sources Tests 2>/dev/null || true

Repository: dashpay/DashUIKit

Length of output: 12451


🌐 Web query:

SwiftUI presentationBackground macOS availability macOS 13 documentation

💡 Result:

The presentationBackground(:) modifier in SwiftUI is available on macOS starting with macOS 13.3 [1][2]. It allows you to customize the background of modal presentations such as sheets, popovers, and full-screen covers [3][4]. Key details regarding this modifier include: Availability: It was introduced in iOS 16.4 and macOS 13.3 [1][2]. Functionality: The modifier applies a ShapeStyle (such as a color, gradient, or material) to the background of an enclosing presentation [5][3]. A secondary version, presentationBackground(alignment:content:), allows for more complex, custom view backgrounds [6][3]. Platform Behavior: Unlike the standard background(:) modifier, presentationBackground(_:) automatically fills the entire presentation area and supports translucency, allowing underlying views to show through when using appropriate styles [5][7][4]. When using this modifier, ensure that nested container views like List or Form have their default backgrounds disabled (e.g., using.scrollContentBackground(.hidden)) if you wish for your custom presentation background to be visible [3].

Citations:


Apply the presentation background on macOS 13.3 and later.

presentationBackground is available on macOS 13.3+, but the #if os(iOS) branch excludes macOS. The background parameter therefore has no effect on macOS presentations. Add a macOS 13.3 availability branch or narrow the API documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/BottomSheet.swift` around lines 190 - 206,
Update the macOS path in the availability-gated modifier flow around
SelfSizingSheetModifier so presentationBackground(background) is applied on
macOS 13.3 and later. Keep the existing iOS-specific corner-radius handling
intact, and ensure older macOS versions continue using the fallback behavior.

Source: Coding guidelines

Comment on lines +305 to +326

@available(iOS 17, macOS 14, *)
#Preview("BottomSheet Custom Background") {
BottomSheet(
title: "Bottom Sheet",
showBackButton: .constant(false),
fillsHeight: false,
background: .dash.secondaryBackground
) {
VStack(alignment: .leading, spacing: 12) {
Text("Cards on a tinted sheet")
.dashFont(.calloutMedium)
.foregroundColor(.dash.primaryText)

Text("The host picks the fill; cards drawn on top keep their own.")
.dashFont(.body)
.foregroundColor(.dash.secondaryText)
.modifier(MenuViewModifier())
}
.padding()
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="Sources/DashUIKit/Components/BottomSheet.swift"
rg -n -B 8 -A 4 '`#Preview`|`#if` DEBUG|`#endif`' "$file"

Repository: dashpay/DashUIKit

Length of output: 2543


Guard all #Preview declarations with #if DEBUG and #endif. These previews use iOS 17 and macOS 14 availability while BottomSheet supports iOS 14 and macOS 11.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/DashUIKit/Components/BottomSheet.swift` around lines 305 - 326, Wrap
the `#Preview` declaration for “BottomSheet Custom Background” in `#if` DEBUG and a
matching `#endif`, preserving its existing iOS 17/macOS 14 availability and
preview content.

Source: Coding guidelines

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants