Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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