Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,7 @@ fastlane/screenshots

BSWInterfaceKit-*.xcarchive
BSWInterfaceKit.xcframework.zip
BSWInterfaceKit.xcframework
BSWInterfaceKit.xcframework

# Graphify generated output
graphify-out/
35 changes: 35 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Repository Instructions

## Project Context Docs

This repository has Markdown documentation in `Docs/` with package architecture, public UI surface summaries, platform support notes, decisions and pending work.

When making code changes in this repository:

1. Check whether `Docs/` exists.
2. If the change affects public APIs, UI behavior, SwiftUI/UIKit behavior, Android Skip behavior, view-model lifetime, async loading/error handling, navigation, media/social integrations, styling, snapshot expectations or pending work, update the relevant Markdown notes before finishing.
3. Do not update docs for purely internal refactors, variable renames, formatting, test-only changes or cleanup that does not change project context.
4. Prefer focused notes under `Docs/features/`, `Docs/decisions/`, `Docs/context/` or `Docs/todo/` instead of only appending to the index.
5. If documentation should change but the right update is ambiguous, mention the documentation gap in the final response.

Package ownership:

- `Docs/` is the source of truth for `BSWInterfaceKit` package context, public UI surface summaries, platform support notes and known pending work.
- DocC comments and Swift Package Index documentation remain the API reference for symbol-level documentation.

## Graphify

Graphify output in `graphify-out/` is a generated navigation index for architecture, dependency and documentation questions. Commit the generated output so agents can read the graph even when the Graphify CLI is not installed locally.

- Use `graphify-out/GRAPH_REPORT.md`, `graphify-out/graph.html` or `graphify query ... --graph graphify-out/graph.json` when they help orient codebase exploration.
- If Graphify is unavailable, read the committed `graphify-out/GRAPH_REPORT.md` and `graphify-out/graph.json` directly, then continue with normal repository exploration using `rg`, source files and `Docs/`.
- Treat Graphify as derived context only. `Docs/` remains the source of truth for package context, public UI surface summaries, platform support notes and pending work.
- Do not replace required `Docs/` updates with Graphify output.
- Do not edit generated files under `graphify-out/` by hand.
- Regenerate Graphify after large merges, broad refactors, API/doc changes or when graph freshness matters for the task.
- Prefer `graphify update .` for code-only changes. Use a full `graphify extract . --mode deep` only when docs, PDFs, images or semantic relationships need to be refreshed.

## GitHub PR Conventions

- Do not prefix pull request titles with `[codex]`.
- Use plain English PR titles that describe the change directly.
35 changes: 35 additions & 0 deletions Docs/00-index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# BSWInterfaceKit Knowledge Base

Last updated: 2026-06-23.

This directory is the source of package context for `BSWInterfaceKit`: shared UIKit and SwiftUI components, Android Skip Compose primitives, Objective-C compatibility shims, view/controller helpers, data sources, presentation utilities and pending technical work.

## Quick Start

- [Project overview](context/project-overview.md)
- [Module map](context/module-map.md)
- [Platform support](context/platform-support.md)
- [SwiftUI async components](features/swiftui-async.md)
- [SwiftUI modifiers and state surfaces](features/swiftui-modifiers.md)
- [UIKit views and controllers](features/uikit-views-and-controllers.md)
- [Data sources and collection layouts](features/data-sources-and-layouts.md)
- [Media, social and in-app integrations](features/media-social-integrations.md)
- [Android Skip components](features/android-skip.md)
- [Styling and extensions](features/styling-and-extensions.md)
- [Objective-C compatibility](features/objective-c-compatibility.md)
- [Technical pending](todo/pending-technical.md)

## Decisions

- [001 - Shared UI foundation package](decisions/001-shared-ui-foundation-package.md)
- [002 - Plain Android Compose primitives](decisions/002-plain-android-compose-primitives.md)

## Systems

- Package: `BSWInterfaceKit`
- Package manifest: `Package.swift`
- Runtime source: `Sources/BSWInterfaceKit/`
- Objective-C shim target: `Sources/BSWInterfaceKitObjC/`
- Android Skip source: `Sources/BSWInterfaceKit/Skip/`
- Tests and snapshots: `Tests/BSWInterfaceKitTests/`
- Public API docs: Swift Package Index DocC documentation
19 changes: 19 additions & 0 deletions Docs/_templates/adr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# NNN - Title

Date: YYYY-MM-DD

## Status

Proposed

## Context

What problem or tradeoff is being decided?

## Decision

What are we doing?

## Consequences

What becomes easier, harder or intentionally out of scope?
48 changes: 48 additions & 0 deletions Docs/context/module-map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Module Map

## SwiftUI

`Sources/BSWInterfaceKit/SwiftUI/` contains async state views, infinite scrolling, photo rendering, JSON tree display, HUD/blocking task/action bar modifiers, view builders, popover helpers, placeholder protocols and operation tracing.

Important public surfaces include:

- `AsyncView`
- `AsyncButton`
- `InfiniteVerticalScrollView`
- `InfiniteScrollingDataSource`
- `PagingHandler`
- `PhotoView`
- `JSONTreeView`
- `HUDState` and `HUDConfiguration`
- `performBlockingTask(...)`
- `AsyncOperationTracer`

## UIKit

UIKit source covers reusable views, cells, view controllers, behaviors, extensions, presentations and data sources.

Important areas include:

- `AvatarView`, `ErrorView`, `LoadingView`, `RangeSlider`, `CheckboxButton`, `SeparatorView`, `LinkAwareLabel` and `ScrollableStackView`.
- `ContainerViewController`, `RootViewController`, `BottomContainerViewController`, `PhotoGalleryViewController` and `TextFieldAlertController`.
- `CollectionViewDiffableDataSource`, `PagingCollectionViewDiffableDataSource` and `SelectableTableViewDataSource`.
- `CardPresentation` and `MarqueePresentation`.
- `MediaPickerBehavior`, `MessageComposerBehavior`, `UpdatePageControlOnScrollBehavior` and UIKit in-app notification helpers.

## Android Skip

`Sources/BSWInterfaceKit/Skip/` contains Android-only Compose primitives such as `BSWAsyncView`, `BSWAsyncButton`, `BSWSheet`, `BSWNavDisplay`, `BSWBackButton`, blocking task/HUD helpers and Swift view-model retention utilities.

## Objective-C Compatibility

`Sources/BSWInterfaceKitObjC/` exposes Objective-C-compatible layout, transition and utility shims used by older UIKit code:

- `BSWCollectionViewLeftAlignedLayout`
- `BSWZoomTransition`
- `BSWZoomImageTransition`
- `UIView+Utilities`
- `UIViewController+Utilities`

## Integrations

The package includes media picking, mail/message composer helpers, social authentication, in-app notifications and Nuke-backed image utilities.
32 changes: 32 additions & 0 deletions Docs/context/platform-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Platform Support

`BSWInterfaceKit` is Apple UI-first and has an explicit Skip/Android path for selected SwiftUI-equivalent infrastructure.

## Apple Platforms

The package declares iOS, macOS and watchOS support in `Package.swift`. Many UIKit APIs are guarded with `canImport(UIKit...)`, `os(iOS)` or availability checks, so support varies by symbol.

Apple-specific areas include:

- UIKit views, view controllers, cells, collection/table data sources and presentation controllers.
- Media picking and thumbnail generation, guarded by Photos, UIKit and related frameworks.
- Social authentication, currently iOS-only.
- Objective-C shim target used by UIKit code.
- Nuke image-loading dependencies, included only for Apple platforms through dependency conditions.

The dependency condition also includes Mac Catalyst, tvOS and visionOS for Apple-only dependencies, but those platforms are not currently declared as minimum package platforms.

## Android Via Skip

When `SKIP_ENABLED` is present, the package adds Skip dependencies and the Skip plugin:

- `skip`
- `skip-fuse-ui`
- `SkipFuseUI`
- `skipstone` plugin

Android-only source lives under `Sources/BSWInterfaceKit/Skip/` and is intentionally implemented as plain Compose infrastructure. Product apps should wrap these primitives to apply strings, branding, styling and feature-specific defaults.

## Compatibility Rule

New shared SwiftUI-style APIs should decide explicitly whether they need Android parity. UIKit and AppKit-adjacent APIs must remain guarded with import or availability checks. Android Compose APIs should keep the `BSW` prefix used in the README to avoid collisions with Skip-generated SwiftUI symbols.
23 changes: 23 additions & 0 deletions Docs/context/project-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Project Overview

`BSWInterfaceKit` is a Swift Package Manager library containing shared user-interface infrastructure for TheLeftBit apps. It combines UIKit components, SwiftUI views and modifiers, image/media helpers, social authentication helpers, snapshot-tested UI utilities and Android-only Compose primitives used by Skip builds.

## Package Shape

- Product: `BSWInterfaceKit`
- Swift target: `Sources/BSWInterfaceKit`
- Objective-C target: `Sources/BSWInterfaceKitObjC`
- Test target: `Tests/BSWInterfaceKitTests`
- Swift tools version: `6.2`
- Minimum declared platforms: iOS 17, macOS 15 and watchOS 11

## Dependencies

- `BSWFoundation` provides shared foundation helpers and aliases.
- `Nuke`, `NukeExtensions` and `NukeUI` power image loading on Apple platforms.
- `swift-snapshot-testing` is used by the test target.
- `skip` and `skip-fuse-ui` are included only when `SKIP_ENABLED` is present.

## Documentation Responsibilities

Use `Docs/` for package-level context: why components exist, which platform boundaries matter, how public UI behavior should be consumed and what maintenance work remains. Keep DocC comments as the source for symbol-level API details.
23 changes: 23 additions & 0 deletions Docs/decisions/001-shared-ui-foundation-package.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 001 - Shared UI Foundation Package

Date: 2026-06-23

## Status

Accepted

## Context

TheLeftBit apps need reusable UI infrastructure for common loading, error, media, presentation, data-source and styling patterns. Duplicating this behavior in apps increases inconsistency and makes cross-app fixes slower.

## Decision

`BSWInterfaceKit` remains a Swift Package Manager library that exports one product, `BSWInterfaceKit`, composed of the Swift target and the Objective-C shim target.

Package-level context lives in `Docs/`; symbol-level reference remains in DocC comments and Swift Package Index.

## Consequences

- Public UI behavior changes should be treated as shared-library changes.
- Snapshot-tested components should preserve visual behavior unless the visual change is intentional.
- Product-specific strings, branding and feature policy should usually live in app wrappers, not in this package.
21 changes: 21 additions & 0 deletions Docs/decisions/002-plain-android-compose-primitives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 002 - Plain Android Compose Primitives

Date: 2026-06-23

## Status

Accepted

## Context

Skip apps need Android equivalents for shared async UI patterns, navigation, sheets and view-model retention. These primitives must be reusable across products with different styling and copy.

## Decision

Android-only Compose APIs under `Sources/BSWInterfaceKit/Skip/` stay plain and infrastructure-focused. They use the `BSW` prefix and are intended to be wrapped by product apps for localized strings, branded visuals and feature-specific defaults.

## Consequences

- Shared Android APIs should avoid product-specific copy and styling.
- Lifecycle and Swift view-model retention behavior belongs in this package.
- App-level wrappers own visual polish, localization and domain-specific behavior.
26 changes: 26 additions & 0 deletions Docs/features/android-skip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Android Skip Components

Android support lives in `Sources/BSWInterfaceKit/Skip/` and is written as plain Compose infrastructure.

## Public Components

- `BSWAsyncView` mirrors the async loading/error/content pattern.
- `BSWAsyncButton` wraps suspend actions with inline or blocking loading states.
- `BSWSheet` provides modal bottom sheet helpers with scoped Swift view-model ownership.
- `BSWNavDisplay` wires Navigation 3 with push/pop transitions and per-entry view-model stores.
- `BSWBackButton` provides a Material back button.
- `BlockingHudDialog`, blocking task state and related helpers support modal async work.
- `BSWSwiftViewModelHolder`, `swiftViewModel(...)` and scoped owner helpers retain Swift-backed state correctly inside Compose lifecycles.

## Design Rule

The README states that Android APIs intentionally remain plain infrastructure. Apps should wrap them for:

- Localization.
- Product-specific loading and error views.
- Custom button and sheet styling.
- Feature-specific navigation entry providers.

## Naming Rule

Android-only Compose APIs use the `BSW` prefix to avoid collisions with bridged SwiftUI symbols generated by Skip.
25 changes: 25 additions & 0 deletions Docs/features/data-sources-and-layouts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Data Sources And Layouts

This package includes reusable data-source and layout helpers for UIKit collection and table views.

## CollectionViewDiffableDataSource

`CollectionViewDiffableDataSource` subclasses `UICollectionViewDiffableDataSource` and adds:

- Empty view handling through `EmptyConfiguration`.
- Pull-to-refresh support through `PullToRefreshProvider`.
- Snapshot reconfiguration after async refresh.

## Paging Collection Data Source

`PagingCollectionViewDiffableDataSource` adds paging semantics for items conforming to `PagingCollectionViewItem`.

## Selectable Table View Data Source

`SelectableTableViewDataSource` coordinates selectable table cells that conform to `ViewModelReusable`.

## Layouts

`HorizontalPagedCollectionViewLayout` supports horizontally paged collection views with configurable item sizing and alignment.

`BSWCollectionViewLeftAlignedLayout` lives in the Objective-C shim target for legacy left-aligned collection layouts.
27 changes: 27 additions & 0 deletions Docs/features/media-social-integrations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Media, Social And In-App Integrations

This package includes app-integration helpers that sit close to UIKit and platform frameworks.

## Media Picker

`MediaPickerBehavior` presents photo library, camera or files flows and returns a temporary file URL. It supports photo, video and thumbnail requests and can generate thumbnails from video assets.

Because it depends on Photos, UIKit, AVFoundation and related frameworks, it is Apple-only and unavailable on tvOS.

## Mail And Message Composer

`MessageComposerBehavior` wraps mail and message composer delegates to simplify presentation and completion handling.

## Social Authentication

`SocialAuthenticationManager` performs OAuth login through `ASWebAuthenticationSession`. Facebook support is implemented through `SocialAuthenticationManager.FacebookCredentials`.

This area is currently iOS-only.

## In-App Notifications

UIKit and SwiftUI in-app notification helpers provide reusable transient notification presentation. Keep copy and product-specific styling outside this package where possible.

## Scroll And Presentation Behaviors

`UpdatePageControlOnScrollBehavior` keeps `UIPageControl` in sync with horizontal or vertical scrolling. Presentation-related UIKit helpers in this area should stay generic and avoid product-specific copy.
14 changes: 14 additions & 0 deletions Docs/features/objective-c-compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Objective-C Compatibility

`Sources/BSWInterfaceKitObjC/` keeps compatibility shims for older UIKit code and Objective-C-exposed APIs.

## Components

- `BSWCollectionViewLeftAlignedLayout` provides a left-aligned collection view layout.
- `BSWZoomTransition` and `BSWZoomImageTransition` implement zoom-style transitions.
- `UIView+Utilities` and `UIViewController+Utilities` expose layout and controller helpers to Objective-C consumers.
- Headers under `Sources/BSWInterfaceKitObjC/include/` define the public Objective-C surface.

## Maintenance Rule

Changes here can affect Swift and Objective-C consumers. Preserve exported symbol names and headers unless a breaking change is intentional and documented.
24 changes: 24 additions & 0 deletions Docs/features/styling-and-extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Styling And Extensions

`BSWInterfaceKit` exposes a broad set of UIKit, SwiftUI and text utilities. These APIs are easy for downstream apps to depend on, so keep behavior changes conservative.

## Styling

`TextStyler` centralizes attributed text styling and is covered by snapshot tests. `NSAttributedString` helpers cover concatenation, paragraph spacing, links, bolding and attribute application.

Color and font helpers extend UIKit/AppKit/SwiftUI types where available. `LocalizationService` and the `String.localized` helper provide package-level localization lookup for shared UI strings.

## UIKit Extensions

Common extension areas include:

- View layout helpers such as pinning, centering and nib instantiation.
- View controller presentation, containment, error/loading states and async fetch helpers.
- Button, label, text field, image, image view, collection view, table view, content view and stack view utilities.
- Keyboard layout guide helpers.
- `UIScreen`, `UIWindow`, `UIResponder`, `UIEdgeInsets` and `UIActivityIndicatorView.Style` compatibility helpers.
- `isiOSAppOnMac()` for detecting iOS apps running on macOS.

## Models And Protocols

`Photo` models local/remote/empty image state and random colors. `ViewModelConfigurable`, `ViewModelReusable` and `IntrinsicSizeCalculable` support reusable UIKit views and cells.
Loading
Loading