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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ body:
attributes:
label: Package and React versions
description: Include the package, react, react-dom, and browser versions.
placeholder: '@nipe-solutions/react-swipe-actions 0.1.0-alpha.2; react 19.2.8'
placeholder: '@nipe-solutions/react-swipe-actions 1.0.0; react 19.2.8'
validations:
required: true
- type: input
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ permissions:
contents: read

concurrency:
group: npm-nipe-solutions-react-swipe-actions-alpha
group: npm-nipe-solutions-react-swipe-actions-stable
cancel-in-progress: false

jobs:
Expand Down Expand Up @@ -55,7 +55,7 @@ jobs:
- name: Upload verified release artifact
uses: actions/upload-artifact@v7
with:
name: npm-package-alpha
name: npm-package-stable
path: release-artifact
if-no-files-found: error
retention-days: 3
Expand All @@ -77,7 +77,7 @@ jobs:
- name: Download verified release artifact
uses: actions/download-artifact@v7
with:
name: npm-package-alpha
name: npm-package-stable
path: release-artifact
- name: Validate and publish verified artifact
env:
Expand All @@ -87,12 +87,12 @@ jobs:
run: |
set -euo pipefail

if [[ "$RELEASE_CHANNEL" != "alpha" ]]; then
echo "Release channel must be alpha" >&2
if [[ "$RELEASE_CHANNEL" != "latest" ]]; then
echo "Release channel must be latest" >&2
exit 1
fi

expected_tarball="nipe-solutions-react-swipe-actions-0.1.0-alpha.3.tgz"
expected_tarball="nipe-solutions-react-swipe-actions-1.0.0.tgz"
if [[ ! "$RELEASE_TARBALL" =~ ^[A-Za-z0-9._-]+$ ]] || [[ "$RELEASE_TARBALL" != "$expected_tarball" ]]; then
echo "Unsafe release tarball: expected $expected_tarball" >&2
exit 1
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.worktrees/
.superpowers/
node_modules/
dist/
coverage/
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

All notable changes are documented in this file.

## [1.0.0] - 2026-09-29

### Added

- Declared the existing component, type, stylesheet, CSS-variable, data-attribute,
keyboard, logical-side, and controlled-state surfaces stable.
- Added protected stable publication through the npm `latest` tag with OIDC
provenance, exact artifact validation, and a SHA-512 manifest.

### Fixed

- Isolated packed-consumer installs from unrelated npm script policy while
retaining caller registry and network configuration.
- Updated the development-only `undici` resolution used through `jsdom` to a
patched version.

### Verified

- Rechecked React 18 and 19 consumers, ESM and CommonJS loading, TypeScript,
SSR and hydration, Vite, bundle budgets, and the public package inventory.
- Ran the automated Chromium, Firefox, and WebKit interaction matrix together
with keyboard and axe coverage. No physical-device or human screen-reader
run is claimed for this release.

## [0.1.0-alpha.3] - 2026-09-05

### Fixed
Expand Down
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Contributing

Issues and pull requests are welcome for reproducible defects, documentation,
tests, and focused improvements to the public contract. The package is in an
alpha phase; discuss a new public API or broad interaction model before writing
an implementation.
tests, and focused improvements to the public contract. Discuss a new public API
or broad interaction model before writing an implementation; compatibility is
maintained within the current major release.

## Local setup

Expand Down Expand Up @@ -42,9 +42,9 @@ not install or run the browser matrix.
evidence. Physical directions are browser behavior, not public state.
- Include documentation updates when the exported API, CSS contract, browser
policy, or limitations change.
- No Changesets integration is configured for this alpha. Describe the
user-visible changelog entry in the pull request; maintainers update
[CHANGELOG.md](CHANGELOG.md) when preparing a release.
- Describe the user-visible changelog entry in the pull request. Maintainers
update [CHANGELOG.md](CHANGELOG.md) while preparing a release; the repository
does not use Changesets.

## Review evidence

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ controlled or default open state. Keep server and first-client state consistent.
Support targets the current and previous major Chrome/Chromium, Edge, Firefox,
and Safari releases, plus modern Chrome Android and Mobile Safari. It requires
Pointer Events, `ResizeObserver`, animation frames, CSS custom properties, and
logical properties. v1 is an alpha and intentionally excludes generic gesture
logical properties. The 1.x contract intentionally excludes generic gesture
hooks, nested swipe roots, portals, React Native, `asChild`, and application
list lifecycle features.

Expand Down
7 changes: 3 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

## Supported versions

Security fixes are evaluated for the current `0.1.0-alpha.0` development line.
Older prereleases are not supported. This policy describes the repository before
the first npm publication; it does not claim that an unlisted registry version
is supported.
Security fixes are evaluated for the current `1.x` release line. Prereleases and
superseded release lines are not supported unless a security advisory states
otherwise.

## Reporting a vulnerability

Expand Down
15 changes: 9 additions & 6 deletions docs/REAL_DEVICE_QA.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ An unchecked manual item is pending, not an implied pass.

## Automated coverage

CI exercises Chromium, Firefox, and WebKit with real browser pointer sequences.
It covers horizontal intent, vertical-scroll arbitration, slow and fast release,
pause before release, direction reversal, full-swipe activation and cancellation,
re-grab during settle, group handoff, interactive children, keyboard disclosure,
RTL, reduced motion, resize, pointer cancellation, and accessibility scans.
CI exercises Chromium, Firefox, and WebKit with browser pointer sequences. It
covers horizontal intent, vertical-scroll arbitration, slow and fast release,
pause before release, direction reversal, full-swipe activation and
cancellation, re-grab during settle, group handoff, interactive children,
keyboard disclosure, RTL, reduced motion, resize, pointer cancellation, and axe
accessibility scans.

Desktop browser automation cannot faithfully reproduce OS navigation-edge
gestures, device touch latency, orientation sensors, or assistive technology on
Expand Down Expand Up @@ -42,4 +43,6 @@ outside a nested scroll container.

## Manual verified

No physical-device run has been recorded for this release candidate yet.
No physical-device or human screen-reader run was performed for the 1.0.0
release. The automated browser, keyboard, and axe results are the recorded
release evidence; they do not stand in for the unchecked manual items above.
18 changes: 9 additions & 9 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ procedure for later versions.
## Preconditions

- Use Node.js 24 and npm 11.19.0 with a clean, reviewed worktree.
- Confirm the intended version, prerelease tag, and matching unreleased entry
in [CHANGELOG.md](../CHANGELOG.md).
- Confirm the intended version, npm dist-tag, and matching dated entry in
[CHANGELOG.md](../CHANGELOG.md).
- Confirm package metadata, exports, license, and repository links still match
the [public API](../README.md) and [architecture](architecture.md).
- Review the current and previous browser-major policy in
[architecture](architecture.md#browser-policy), including any manual
mobile-edge and container evidence that automated desktop browsers cannot
establish.
[architecture](architecture.md#browser-policy). Record manual mobile-edge,
screen-reader, and container evidence when available; do not infer it from
desktop automation.

Install and run the quality evidence:

Expand All @@ -37,7 +37,7 @@ Build and inspect the exact tarball contents before release automation uses it:
```bash
npm run build:dist
npm pack --json
tar -tf nipe-solutions-react-swipe-actions-0.1.0-alpha.3.tgz
tar -tf nipe-solutions-react-swipe-actions-1.0.0.tgz
npm publish --dry-run --provenance --access public
```

Expand All @@ -61,6 +61,6 @@ bypass a missing trusted-publisher configuration. Record the workflow run,
published version, provenance link, tarball inventory, browser evidence, and
any manual-device checks with the release record.

Each prerelease is published only after a maintainer explicitly approves the
release, confirms the protected environment and triggers the workflow. Until
then, this guide remains a review procedure and dry-run checklist.
Each release is published only after a maintainer explicitly approves it,
confirms the protected environment, and triggers the workflow. Until then, this
guide remains a review procedure and dry-run checklist.
20 changes: 11 additions & 9 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,12 @@ content layer because JavaScript owns direct drag and settle coordinates.

## Limitations

The alpha does not provide row removal, undo, confirmation, async state, generic
gesture hooks, virtualization, portals, drag and drop, `asChild`, React Native,
or nested swipe roots. It has no runtime integration dependency for dialogs,
drawers, or Bottom Sheet components. Those containers must allow vertical pan
ownership and should be tested with their actual gesture configuration.
The package does not provide row removal, undo, confirmation, async state,
generic gesture hooks, virtualization, portals, drag and drop, `asChild`, React
Native, or nested swipe roots. It has no runtime integration dependency for
dialogs, drawers, or Bottom Sheet components. Those containers must allow
vertical pan ownership and should be tested with their actual gesture
configuration.

Performance cost currently scales with rendered rows and observed elements.
Applications with very large datasets should virtualize at the list layer. CSS
Expand All @@ -262,10 +263,11 @@ keyboard/focus, RTL, reduced motion, SSR import/rendering, browser interaction,
package consumers, and CSS/API boundaries.

Manual checks are recorded separately and are never implied by an automated
pass. In particular, OS browser back-edge gestures on physical Mobile Safari and
Chrome Android require device testing because desktop automation cannot
faithfully reproduce navigation-edge ownership. Bottom Sheet integrations also
need checks against the consuming sheet version and configuration.
pass. No physical-device or human screen-reader run is part of the 1.0.0 release
record. OS browser back-edge gestures on physical Mobile Safari and Chrome
Android require device testing because desktop automation cannot faithfully
reproduce navigation-edge ownership. Bottom Sheet integrations also need checks
against the consuming sheet version and configuration.

### Native-feel interaction matrix

Expand Down
4 changes: 2 additions & 2 deletions docs/performance.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Performance evidence

This document records measured evidence for the alpha package. It is not a claim
that every application or device will match these timings.
This document records measured evidence for the package. It is not a claim that
every application or device will match these timings.

## Fixture

Expand Down
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nipe-solutions/react-swipe-actions",
"version": "0.1.0-alpha.3",
"version": "1.0.0",
"description": "Composable swipe actions for React.",
"license": "MIT",
"repository": {
Expand All @@ -14,7 +14,7 @@
"publishConfig": {
"access": "public",
"provenance": true,
"tag": "alpha"
"tag": "latest"
},
"type": "module",
"engines": {
Expand Down Expand Up @@ -55,7 +55,7 @@
"verify:website:browser": "node scripts/verify-website.mjs",
"test:api": "node scripts/check-public-api.mjs",
"test:size": "node scripts/check-bundle-size.mjs",
"test:package": "npm run build:dist && node --test test/package/verify-package.test.mjs",
"test:package": "npm run build:dist && node --test test/package/foundation.test.mjs test/package/verify-package.test.mjs",
"test:workflows": "node --test scripts/verify-workflows.test.mjs",
"test:clean-check": "node --test scripts/verify-clean-check.test.mjs",
"release:check": "node scripts/verify-release.mjs",
Expand Down
36 changes: 29 additions & 7 deletions scripts/verify-package.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ try {
...installPackages,
],
consumer,
{
NPM_CONFIG_ALLOW_SCRIPTS: undefined,
npm_config_allow_scripts: undefined,
},
)

const installedPackage = JSON.parse(
Expand Down Expand Up @@ -258,15 +262,21 @@ function validatePackedFiles(files) {
)
}

function run(command, args, cwd = repositoryRoot) {
function run(command, args, cwd = repositoryRoot, environmentOverrides = {}) {
const environment = {
...process.env,
npm_config_audit: 'false',
npm_config_fund: 'false',
npm_config_update_notifier: 'false',
...environmentOverrides,
}
for (const [name, value] of Object.entries(environment)) {
if (value === undefined) delete environment[name]
}

return execFileAsync(command, args, {
cwd,
env: {
...process.env,
npm_config_audit: 'false',
npm_config_fund: 'false',
npm_config_update_notifier: 'false',
},
env: environment,
maxBuffer: 10 * 1024 * 1024,
})
}
Expand Down Expand Up @@ -316,6 +326,14 @@ async function validateSourceDocumentation() {
/^## \[0\.1\.0-alpha\.0\] - \d{4}-\d{2}-\d{2}$/m,
'CHANGELOG.md must contain the dated 0.1.0-alpha.0 section',
)
assert.match(
changelog,
new RegExp(
`^## \\[${escapeRegExp(packageJson.version)}\\] - \\d{4}-\\d{2}-\\d{2}$`,
'm',
),
`CHANGELOG.md must contain a dated ${packageJson.version} section`,
)

const contributing = files.get('CONTRIBUTING.md')
assert.ok(contributing, 'CONTRIBUTING.md must be readable')
Expand Down Expand Up @@ -442,6 +460,10 @@ function typescriptBlocks(source) {
)
}

function escapeRegExp(value) {
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}

async function pathExists(target) {
try {
await access(target)
Expand Down
Loading