Skip to content
Merged
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
56 changes: 0 additions & 56 deletions .github/workflows/deploy-example-gallery.yml

This file was deleted.

103 changes: 103 additions & 0 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Deploy Website

# Run only when a pull request is merged into main (not on every PR event),
# plus a manual trigger.
on:
pull_request:
types: [closed]
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
# Skip PRs that were closed without merging; always allow manual runs.
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true }}
runs-on: ubuntu-latest

steps:
# Check out the post-merge main so we deploy exactly what landed.
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref || github.ref }}
fetch-depth: 0

- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version-file: .fvmrc
cache: true

- name: Cache pub dependencies
uses: actions/cache@v4
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-

- name: Configure Pages
uses: actions/configure-pages@v5

- name: Install dependencies
run: flutter pub get

# Pinned to match the project's jaspr ^0.23.1, and run under the
# Flutter-pinned Dart so the build daemon snapshots match the SDK (a
# mismatched Dart crashes the daemon with "Invalid kernel binary format").
- name: Install Jaspr CLI
run: dart pub global activate jaspr_cli 0.23.1

- name: Build Tailwind CSS
working-directory: website
run: tool/styles.sh --minify

- name: Build website
working-directory: website
run: dart pub global run jaspr_cli:jaspr build --verbose

- name: Verify build output
working-directory: website/build/jaspr
run: |
set -e
ls -la
test -f index.html || { echo "ERROR: index.html not found"; exit 1; }
test -f main.client.dart.js || { echo "ERROR: client bundle not found"; exit 1; }
echo "Build output OK"

# The project Pages site lives at the /dnd_kit/ subpath. jaspr build has no
# --base-href flag and Document emits <base href="/"/>, so rewrite it here
# (asset URLs in index.html are relative and resolve against this base).
- name: Set base href for the project subpath
working-directory: website/build/jaspr
run: |
set -e
sed -i 's|<base href="/"/>|<base href="/dnd_kit/"/>|' index.html
grep -q '<base href="/dnd_kit/"/>' index.html
touch .nojekyll

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: website/build/jaspr

deploy:
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest

steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
3 changes: 3 additions & 0 deletions docs/product/api-principles.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ warnings without depending only on debug assertions.
- The browser adapter supports pointer, mouse, touch, and keyboard activation,
DOM measuring, overlay rendering, browser auto-scroll execution, and
live-region accessibility over the shared engine.
- Shared accessibility copy customization belongs in the pure-Dart
`DndAnnouncements` contract; adapter execution of those announcements stays
local to Flutter semantics APIs and Jaspr live regions.
- Browser access must remain SSR-safe: no DOM requirement at import time, and
browser-only behavior stays guarded behind runtime checks.
- Where parity is portable, Flutter and Jaspr should preserve the same
Expand Down
4 changes: 3 additions & 1 deletion docs/product/package-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Owns:
- drag state and session models
- the framework-neutral drag runtime (`DndRuntime`)
- the measuring-cache contract (`DndMeasuringRegistry`)
- the shared accessibility announcement contract (`DndAnnouncements`)
- collision detector contracts and built-in algorithms
- modifier contracts and pure Dart modifiers
- sensor contracts and the shared pointer sensor
Expand Down Expand Up @@ -118,7 +119,8 @@ Owns:
- live-region accessibility hooks and accessible labels/descriptions

Jaspr inherits the shared single-container sortable strategies (vertical list,
horizontal list, and grid) from `dnd_kit`. Multi-container sorting remains a
horizontal list, and grid) from `dnd_kit`, along with the shared
`DndAnnouncements` accessibility contract. Multi-container sorting remains a
Flutter-only experimental feature for now.

Must not:
Expand Down
61 changes: 55 additions & 6 deletions docs/product/release-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,49 @@ across the current package family:
First story:
`docs/stories/phase-22-coordinated-family-release/US-069-publish-current-family-dev-line/overview.md`.

## Phase 23 - Flutter Accessibility Hardening

Close the remaining adapter accessibility gap after Jaspr's Phase 15 hardening
by giving `dnd_kit_flutter` a first-class Flutter-native accessibility story
for the next package patch release:

- configurable semantics labels and usage instructions for draggables and drag
handles;
- optional assistive-technology announcements for drag lifecycle changes;
- focus-stable keyboard dragging with adapter-local execution over the shared
runtime;
- package docs and changelog preparation for `dnd_kit_flutter 0.3.1`.

Phase README: `docs/stories/phase-23-flutter-accessibility-hardening/README.md`.

## Phase 24 - Shared Accessibility Contract

Remove duplicate accessibility contract code now that both adapters expose a
first-class a11y surface:

- move `DndAnnouncements` and its pure-Dart builders into `dnd_kit`;
- rewire `dnd_kit_flutter` and `dnd_kit_jaspr` to reuse the shared contract;
- keep Flutter semantics execution and Jaspr live-region execution
adapter-local;
- shift default/custom announcement unit proof into the core package.

Phase README: `docs/stories/phase-24-shared-accessibility-contract/README.md`.

## Phase 25 - Coordinated Family Patch Release

Close the prepared `0.3.1` package line as one auditable family publication:

- publish `dnd_kit 0.3.1` first as the shared dependency root;
- publish `dnd_kit_flutter 0.3.1` second against `dnd_kit: ^0.3.1`;
- publish `dnd_kit_jaspr 0.3.1` third against `dnd_kit: ^0.3.1`;
- keep changelog truth, family dry-run proof, and the maintainer-run publish
order explicit in one release packet.

Phase README: `docs/stories/phase-25-coordinated-family-patch-release/README.md`.

## Current State

The repository has implemented work through `US-068`. The Flutter adapter, the
The repository has implemented work through `US-073`. The Flutter adapter, the
pure Dart engine, and the Jaspr adapter share the `dnd_kit` brand family under
the post-US-060 topology, the workspace is unified under the Phase 17 toolchain,
and both adapters now ship a sortable preset over the shared engine. Phase 19
Expand All @@ -235,8 +275,17 @@ mirrors the same contract for horizontal browser scroll containers while
keeping its auto-scroll execution component-owned. Phase 20 closes the runnable
Jaspr example gap with `examples/jaspr_example_gallery`, a tabbed feature
gallery covering drag/drop, sortable, auto-scroll, accessibility, and
modifiers over the shared runtime. Phase 21 then closes the first gallery-found
adapter regression by restoring `DndDragOverlay` rebinding after a controlled
`DndScope` controller swap. Future work should extend this roadmap through new
product docs, story packets, and decisions rather than by reviving the old
umbrella/core topology from the historical specs.
modifiers over the shared runtime. Phase 21 then closes the next gallery-found
adapter regressions by restoring `DndDragOverlay` rebinding after a controlled
`DndScope` controller swap and fixing the Jaspr SSR handle-sync assertion.
Phase 23 then closes Flutter accessibility hardening by adding semantics
labels/hints, handle accessibility, and lifecycle announcements in the
`dnd_kit_flutter 0.3.1` line. Phase 24 then removes duplicate announcement
contract code by moving `DndAnnouncements` into `dnd_kit` while keeping Flutter
semantics execution and Jaspr live-region execution adapter-local. Phase 25 is
the closed release packet for those prepared package deltas as a coordinated
stable `0.3.1` family release; local proof passed and the three packages were
published in dependency order on 2026-06-20. Future work
should extend this roadmap through new product docs, story packets, and
decisions rather than by reviving the old umbrella/core topology from the
historical specs.
2 changes: 1 addition & 1 deletion docs/stories/backlog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ the work is selected or when a product decision needs a durable place to land.
| Epic | Description | Status |
| --- | --- | --- |
| Jaspr multi-container sortable | Bring `SortableContainer` / `SortableMultiContainer` to `dnd_kit_jaspr` for cross-container sorting parity with Flutter. These helpers are framework-neutral pure Dart but currently live only in `dnd_kit_flutter`; preferred path is hoisting them into the `dnd_kit` engine (engine + both adapters republish), per ADR 0019's remaining-gap note. Deferred from US-062. | unsliced |
| Jaspr draggable SSR handle-sync assertion (→ 0.3.1) | During static/SSR pre-render, `_DndDraggableState._scheduleHandleStateSync` (`packages/dnd_kit_jaspr/lib/src/widgets/draggable.dart` ~523) schedules a microtask `setState`, tripping the framework assertion `owner._debugCurrentBuildTarget != null`. Pre-rendered output is still complete and the client is unaffected (debug-only assert), but it is noisy and contradicts the "SSR-safe" guarantee. Fix: guard the handle-state sync to client-only (`if (!kIsWeb) return;` in `_scheduleHandleStateSync`), add a regression test + CHANGELOG, and **publish `dnd_kit_jaspr` 0.3.1**. Surfaced by `website/` (drag handles under Jaspr static mode). Fixed: `_scheduleHandleStateSync` now guards on `!kIsWeb`; regression test `draggable_ssr_test.dart` (server pre-render) + CHANGELOG + version bump landed. **Pending `pub publish` of `dnd_kit_jaspr` 0.3.1.** | done (unpublished) |
| Jaspr draggable SSR handle-sync assertion (→ 0.3.1) | During static/SSR pre-render, `_DndDraggableState._scheduleHandleStateSync` (`packages/dnd_kit_jaspr/lib/src/widgets/draggable.dart` ~523) schedules a microtask `setState`, tripping the framework assertion `owner._debugCurrentBuildTarget != null`. Pre-rendered output is still complete and the client is unaffected (debug-only assert), but it is noisy and contradicts the "SSR-safe" guarantee. Fix: guard the handle-state sync to client-only (`if (!kIsWeb) return;` in `_scheduleHandleStateSync`), add a regression test + CHANGELOG, and **publish `dnd_kit_jaspr` 0.3.1**. Surfaced by `website/` (drag handles under Jaspr static mode). Fixed in US-070: `_scheduleHandleStateSync` now guards on `!kIsWeb`; regression test `draggable_ssr_test.dart` (server pre-render) + CHANGELOG + version bump landed. Shipped in `dnd_kit_jaspr` 0.3.1 (published 2026-06-20 via US-073). | done |
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ When updating durable proof status, use numeric booleans:
| Integration | Not required; the regression is isolated to the server pre-render path with package-level proof. |
| E2E | Not required. |
| Platform | `fvm dart analyze packages/dnd_kit_jaspr` stays clean. |
| Release | `dnd_kit_jaspr` CHANGELOG records the fix and the package version is bumped to `0.3.1` for a later publish. |
| Release | `dnd_kit_jaspr` CHANGELOG records the fix and the package version is bumped to `0.3.1`, shipped in the coordinated family `0.3.1` publish (US-073). |

## Harness Delta

No Harness process change. Closes the backlog candidate epic "Jaspr draggable
SSR handle-sync assertion (→ 0.3.1)" recorded earlier; the backlog row is marked
done pending `pub publish`.
SSR handle-sync assertion (→ 0.3.1)" recorded earlier; the fix shipped in
`dnd_kit_jaspr` 0.3.1 via the coordinated family publish (US-073).

## Evidence

Expand Down
41 changes: 41 additions & 0 deletions docs/stories/phase-23-flutter-accessibility-hardening/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Phase 23 — Flutter Accessibility Hardening

This phase closes the next adapter-level parity gap after the Jaspr hardening
work in Phase 15. `dnd_kit_flutter` already supports keyboard pickup/move/drop
and a baseline semantics hint from `US-017`, but it does not yet offer the
same first-class accessibility surface that `dnd_kit_jaspr` now exposes for
labels, usage instructions, and drag lifecycle announcements.

The goal is not to copy ARIA or DOM concepts into Flutter. The goal is to
deliver equivalent accessibility outcomes on Flutter's own platform model so
screen-reader and keyboard users can understand, operate, and track drag state
without relying on pointer-only cues. This phase targets the next additive
adapter release, `dnd_kit_flutter 0.3.1`.

## Principle

Flutter accessibility hardening in this phase must:

- preserve `dnd_kit` as the only drag runtime and derive any announcements from
shared controller/runtime state transitions;
- use Flutter-native accessibility primitives (`Semantics`, `Focus`, and
announcement APIs) rather than copying Jaspr's ARIA/live-region surface
literally;
- keep the API additive and backward-compatible for existing draggables,
handles, and sortable flows;
- aim for cross-adapter behavioral parity where it is portable, while allowing
framework-specific implementation details and naming.

## Delivery Sequence

| Story | Scope | Decision |
| --- | --- | --- |
| **US-071** | Add Flutter-native accessibility labels, instructions, handle semantics, and drag lifecycle announcements for `dnd_kit_flutter` | No ADR (adapter-local additive hardening) |

## Validation Ladder

- Widget proof: `flutter test` covers semantics labels/hints, focus retention,
handle behavior, disabled behavior, and lifecycle announcement hooks.
- Package proof: `dart analyze packages/dnd_kit_flutter` stays clean.
- Release proof: package docs and `CHANGELOG.md` record the new accessibility
surface and the package version bump to `0.3.1`.
Loading
Loading