@connextar/house 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +286 -28
- package/dist/changelog/changelog.d.ts +60 -0
- package/dist/changelog/changelog.d.ts.map +1 -0
- package/dist/changelog/changelog.js +61 -0
- package/dist/changelog/changelog.js.map +1 -0
- package/dist/changelog/index.d.ts +2 -0
- package/dist/changelog/index.d.ts.map +1 -0
- package/dist/changelog/index.js +2 -0
- package/dist/changelog/index.js.map +1 -0
- package/dist/editor/block-handle.d.ts +15 -0
- package/dist/editor/block-handle.d.ts.map +1 -0
- package/dist/editor/block-handle.js +106 -0
- package/dist/editor/block-handle.js.map +1 -0
- package/dist/editor/blocks.d.ts +35 -0
- package/dist/editor/blocks.d.ts.map +1 -0
- package/dist/editor/blocks.js +114 -0
- package/dist/editor/blocks.js.map +1 -0
- package/dist/editor/bubble-toolbar.d.ts +11 -0
- package/dist/editor/bubble-toolbar.d.ts.map +1 -0
- package/dist/editor/bubble-toolbar.js +87 -0
- package/dist/editor/bubble-toolbar.js.map +1 -0
- package/dist/editor/content-index.d.ts +2 -0
- package/dist/editor/content-index.d.ts.map +1 -0
- package/dist/editor/content-index.js +2 -0
- package/dist/editor/content-index.js.map +1 -0
- package/dist/editor/content.d.ts +30 -0
- package/dist/editor/content.d.ts.map +1 -0
- package/dist/editor/content.js +256 -0
- package/dist/editor/content.js.map +1 -0
- package/dist/editor/editor.d.ts +52 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +160 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/emoji-index.d.ts +2 -0
- package/dist/editor/emoji-index.d.ts.map +1 -0
- package/dist/editor/emoji-index.js +2 -0
- package/dist/editor/emoji-index.js.map +1 -0
- package/dist/editor/emoji-picker.d.ts +16 -0
- package/dist/editor/emoji-picker.d.ts.map +1 -0
- package/dist/editor/emoji-picker.js +37 -0
- package/dist/editor/emoji-picker.js.map +1 -0
- package/dist/editor/emoji.d.ts +18 -0
- package/dist/editor/emoji.d.ts.map +1 -0
- package/dist/editor/emoji.js +418 -0
- package/dist/editor/emoji.js.map +1 -0
- package/dist/editor/index.d.ts +5 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +6 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/suggestion-popup.d.ts +17 -0
- package/dist/editor/suggestion-popup.d.ts.map +1 -0
- package/dist/editor/suggestion-popup.js +57 -0
- package/dist/editor/suggestion-popup.js.map +1 -0
- package/dist/editor/suggestions.d.ts +93 -0
- package/dist/editor/suggestions.d.ts.map +1 -0
- package/dist/editor/suggestions.js +179 -0
- package/dist/editor/suggestions.js.map +1 -0
- package/dist/editor/ui.d.ts +54 -0
- package/dist/editor/ui.d.ts.map +1 -0
- package/dist/editor/ui.js +58 -0
- package/dist/editor/ui.js.map +1 -0
- package/dist/house.css +333 -0
- package/dist/internal/cx.d.ts +3 -0
- package/dist/internal/cx.d.ts.map +1 -0
- package/dist/internal/cx.js +5 -0
- package/dist/internal/cx.js.map +1 -0
- package/dist/internal/next-link.d.ts +23 -0
- package/dist/internal/next-link.d.ts.map +1 -0
- package/dist/internal/next-link.js +3 -0
- package/dist/internal/next-link.js.map +1 -0
- package/dist/markdown/guide.d.ts +98 -0
- package/dist/markdown/guide.d.ts.map +1 -0
- package/dist/markdown/guide.js +328 -0
- package/dist/markdown/guide.js.map +1 -0
- package/dist/markdown/index.d.ts +4 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +4 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/table-view.d.ts +28 -0
- package/dist/markdown/table-view.d.ts.map +1 -0
- package/dist/markdown/table-view.js +25 -0
- package/dist/markdown/table-view.js.map +1 -0
- package/dist/markdown/table.d.ts +35 -0
- package/dist/markdown/table.d.ts.map +1 -0
- package/dist/markdown/table.js +79 -0
- package/dist/markdown/table.js.map +1 -0
- package/dist/release/changelog.d.ts +72 -0
- package/dist/release/changelog.d.ts.map +1 -0
- package/dist/release/changelog.js +92 -0
- package/dist/release/changelog.js.map +1 -0
- package/dist/release/index.d.ts +3 -0
- package/dist/release/index.d.ts.map +1 -0
- package/dist/release/index.js +3 -0
- package/dist/release/index.js.map +1 -0
- package/dist/release/version.d.ts +33 -0
- package/dist/release/version.d.ts.map +1 -0
- package/dist/release/version.js +57 -0
- package/dist/release/version.js.map +1 -0
- package/dist/trail/index.d.ts +3 -0
- package/dist/trail/index.d.ts.map +1 -0
- package/dist/trail/index.js +3 -0
- package/dist/trail/index.js.map +1 -0
- package/dist/trail/rules.d.ts +44 -0
- package/dist/trail/rules.d.ts.map +1 -0
- package/dist/trail/rules.js +74 -0
- package/dist/trail/rules.js.map +1 -0
- package/dist/trail/trail.d.ts +49 -0
- package/dist/trail/trail.d.ts.map +1 -0
- package/dist/trail/trail.js +188 -0
- package/dist/trail/trail.js.map +1 -0
- package/dist/ux/errors.d.ts +26 -0
- package/dist/ux/errors.d.ts.map +1 -0
- package/dist/ux/errors.js +33 -0
- package/dist/ux/errors.js.map +1 -0
- package/dist/ux/feedback.d.ts +23 -0
- package/dist/ux/feedback.d.ts.map +1 -0
- package/dist/ux/feedback.js +22 -0
- package/dist/ux/feedback.js.map +1 -0
- package/dist/ux/index.d.ts +20 -0
- package/dist/ux/index.d.ts.map +1 -0
- package/dist/ux/index.js +20 -0
- package/dist/ux/index.js.map +1 -0
- package/dist/ux/navigation-index.d.ts +10 -0
- package/dist/ux/navigation-index.d.ts.map +1 -0
- package/dist/ux/navigation-index.js +10 -0
- package/dist/ux/navigation-index.js.map +1 -0
- package/dist/ux/navigation-progress.d.ts +53 -0
- package/dist/ux/navigation-progress.d.ts.map +1 -0
- package/dist/ux/navigation-progress.js +245 -0
- package/dist/ux/navigation-progress.js.map +1 -0
- package/dist/ux/optimistic.d.ts +139 -0
- package/dist/ux/optimistic.d.ts.map +1 -0
- package/dist/ux/optimistic.js +242 -0
- package/dist/ux/optimistic.js.map +1 -0
- package/dist/ux/use-action.d.ts +60 -0
- package/dist/ux/use-action.d.ts.map +1 -0
- package/dist/ux/use-action.js +100 -0
- package/dist/ux/use-action.js.map +1 -0
- package/dist/ux/use-optimistic-list.d.ts +69 -0
- package/dist/ux/use-optimistic-list.d.ts.map +1 -0
- package/dist/ux/use-optimistic-list.js +115 -0
- package/dist/ux/use-optimistic-list.js.map +1 -0
- package/dist/ux/use-optimistic-value.d.ts +40 -0
- package/dist/ux/use-optimistic-value.d.ts.map +1 -0
- package/dist/ux/use-optimistic-value.js +68 -0
- package/dist/ux/use-optimistic-value.js.map +1 -0
- package/docs/ReleaseProcess.md +315 -0
- package/package.json +83 -11
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one thing an optimistic commit has to be able to say: "that didn't work,
|
|
3
|
+
* and here is what to tell the person".
|
|
4
|
+
*
|
|
5
|
+
* The hooks in this folder take a commit function that throws on failure —
|
|
6
|
+
* the only failure contract every transport already has. An app whose client
|
|
7
|
+
* returns a result object instead of throwing wraps it once (see
|
|
8
|
+
* `commitApi` in `lib/api.ts`) rather than teaching this layer its envelope.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ActionError extends Error {
|
|
11
|
+
/** HTTP status, where the transport had one. */
|
|
12
|
+
readonly status?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Whatever the refusal carried. A conflict usually carries the record as it
|
|
15
|
+
* now is, which is what a caller merges into rather than rolling back to.
|
|
16
|
+
*/
|
|
17
|
+
readonly data?: unknown;
|
|
18
|
+
constructor(message: string, options?: {
|
|
19
|
+
status?: number;
|
|
20
|
+
data?: unknown;
|
|
21
|
+
cause?: unknown;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** The wording to show for a thrown value, whatever it turned out to be. */
|
|
25
|
+
export declare function errorMessage(error: unknown, fallback?: string): string;
|
|
26
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/ux/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;gBAEZ,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAMhG;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAyB,GAAG,MAAM,CAItF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one thing an optimistic commit has to be able to say: "that didn't work,
|
|
3
|
+
* and here is what to tell the person".
|
|
4
|
+
*
|
|
5
|
+
* The hooks in this folder take a commit function that throws on failure —
|
|
6
|
+
* the only failure contract every transport already has. An app whose client
|
|
7
|
+
* returns a result object instead of throwing wraps it once (see
|
|
8
|
+
* `commitApi` in `lib/api.ts`) rather than teaching this layer its envelope.
|
|
9
|
+
*/
|
|
10
|
+
export class ActionError extends Error {
|
|
11
|
+
/** HTTP status, where the transport had one. */
|
|
12
|
+
status;
|
|
13
|
+
/**
|
|
14
|
+
* Whatever the refusal carried. A conflict usually carries the record as it
|
|
15
|
+
* now is, which is what a caller merges into rather than rolling back to.
|
|
16
|
+
*/
|
|
17
|
+
data;
|
|
18
|
+
constructor(message, options = {}) {
|
|
19
|
+
super(message, { cause: options.cause });
|
|
20
|
+
this.name = "ActionError";
|
|
21
|
+
this.status = options.status;
|
|
22
|
+
this.data = options.data;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** The wording to show for a thrown value, whatever it turned out to be. */
|
|
26
|
+
export function errorMessage(error, fallback = "Something went wrong") {
|
|
27
|
+
if (error instanceof Error && error.message)
|
|
28
|
+
return error.message;
|
|
29
|
+
if (typeof error === "string" && error)
|
|
30
|
+
return error;
|
|
31
|
+
return fallback;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/ux/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,gDAAgD;IACvC,MAAM,CAAU;IACzB;;;OAGG;IACM,IAAI,CAAW;IAExB,YAAY,OAAe,EAAE,UAAgE,EAAE;QAC7F,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF;AAED,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,QAAQ,GAAG,sBAAsB;IAC5E,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC;IAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* How this layer tells someone what happened, without knowing what the app
|
|
4
|
+
* uses to tell them.
|
|
5
|
+
*
|
|
6
|
+
* A toast library is a design decision, and the whole point of these hooks is
|
|
7
|
+
* that they can be lifted into a shared package. So the hooks report an event
|
|
8
|
+
* and the app decides what an event looks like — one provider at the root,
|
|
9
|
+
* wired to whatever that app already has.
|
|
10
|
+
*/
|
|
11
|
+
export interface ActionFeedback {
|
|
12
|
+
tone: "success" | "error";
|
|
13
|
+
title: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
}
|
|
16
|
+
export type ActionReporter = (feedback: ActionFeedback) => void;
|
|
17
|
+
export declare function ActionFeedbackProvider({ report, children }: {
|
|
18
|
+
report: ActionReporter;
|
|
19
|
+
children: React.ReactNode;
|
|
20
|
+
}): React.JSX.Element;
|
|
21
|
+
/** The app's reporter, or the console fallback. Stable across renders. */
|
|
22
|
+
export declare function useActionReporter(): ActionReporter;
|
|
23
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/ux/feedback.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;AAchE,wBAAgB,sBAAsB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,qBAEjH;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,IAAI,cAAc,CAElD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
const ReporterContext = React.createContext(null);
|
|
5
|
+
/**
|
|
6
|
+
* Without a provider a failure still has to go somewhere: swallowing it is how
|
|
7
|
+
* an optimistic update becomes a lie. The console is a poor place to tell
|
|
8
|
+
* someone something, but it is not silence, and it shows up in a test.
|
|
9
|
+
*/
|
|
10
|
+
const fallbackReporter = (feedback) => {
|
|
11
|
+
if (feedback.tone !== "error")
|
|
12
|
+
return;
|
|
13
|
+
console.error(`[action] ${feedback.title}${feedback.description ? `: ${feedback.description}` : ""}`);
|
|
14
|
+
};
|
|
15
|
+
export function ActionFeedbackProvider({ report, children }) {
|
|
16
|
+
return _jsx(ReporterContext.Provider, { value: report, children: children });
|
|
17
|
+
}
|
|
18
|
+
/** The app's reporter, or the console fallback. Stable across renders. */
|
|
19
|
+
export function useActionReporter() {
|
|
20
|
+
return React.useContext(ReporterContext) ?? fallbackReporter;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/ux/feedback.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAmB/B,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,CAAwB,IAAI,CAAC,CAAC;AAEzE;;;;GAIG;AACH,MAAM,gBAAgB,GAAmB,CAAC,QAAQ,EAAE,EAAE;IACpD,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO;IACtC,OAAO,CAAC,KAAK,CAAC,YAAY,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxG,CAAC,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAyD;IAChH,OAAO,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YAAG,QAAQ,GAA4B,CAAC;AACxF,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB;IAC/B,OAAO,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,gBAAgB,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@connextar/house/ux` — the interface answers the click.
|
|
3
|
+
*
|
|
4
|
+
* Optimistic updates and pending state, with no framework in them: React, and
|
|
5
|
+
* nothing else. The half that needs Next — the navigation bar and the spinner
|
|
6
|
+
* on the link you clicked — is `@connextar/house/ux/navigation`, kept apart so
|
|
7
|
+
* that `next` stays the optional peer dependency it is declared to be. A
|
|
8
|
+
* barrel that re-exported both made it mandatory for anyone importing so much
|
|
9
|
+
* as the pure patch engine, which a smoke test caught before 0.3.0 shipped.
|
|
10
|
+
*
|
|
11
|
+
* What this module needs from the host arrives as a function (`commit`), a
|
|
12
|
+
* provider (`ActionFeedbackProvider`) or a class name — never as an import.
|
|
13
|
+
*/
|
|
14
|
+
export { ActionError, errorMessage } from "./errors.js";
|
|
15
|
+
export { ActionFeedbackProvider, useActionReporter, type ActionFeedback, type ActionReporter } from "./feedback.js";
|
|
16
|
+
export { applyPatches, isRedundant, isTempKey, reconcile, sameRow, settlePatch, shouldDropSettled, supersede, tempKey, type Patch, type PatchKind, type RowKey, } from "./optimistic.js";
|
|
17
|
+
export { useAction, useKeyedAction, type Action, type ActionOptions, type KeyedAction } from "./use-action.js";
|
|
18
|
+
export { useOptimisticList, type OptimisticList, type OptimisticListOptions, type WriteOptions, } from "./use-optimistic-list.js";
|
|
19
|
+
export { useOptimisticValue, type OptimisticValue, type OptimisticValueOptions } from "./use-optimistic-value.js";
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ux/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,SAAS,EACT,SAAS,EACT,OAAO,EACP,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,OAAO,EACP,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,MAAM,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EACL,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/ux/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@connextar/house/ux` — the interface answers the click.
|
|
3
|
+
*
|
|
4
|
+
* Optimistic updates and pending state, with no framework in them: React, and
|
|
5
|
+
* nothing else. The half that needs Next — the navigation bar and the spinner
|
|
6
|
+
* on the link you clicked — is `@connextar/house/ux/navigation`, kept apart so
|
|
7
|
+
* that `next` stays the optional peer dependency it is declared to be. A
|
|
8
|
+
* barrel that re-exported both made it mandatory for anyone importing so much
|
|
9
|
+
* as the pure patch engine, which a smoke test caught before 0.3.0 shipped.
|
|
10
|
+
*
|
|
11
|
+
* What this module needs from the host arrives as a function (`commit`), a
|
|
12
|
+
* provider (`ActionFeedbackProvider`) or a class name — never as an import.
|
|
13
|
+
*/
|
|
14
|
+
export { ActionError, errorMessage } from "./errors.js";
|
|
15
|
+
export { ActionFeedbackProvider, useActionReporter } from "./feedback.js";
|
|
16
|
+
export { applyPatches, isRedundant, isTempKey, reconcile, sameRow, settlePatch, shouldDropSettled, supersede, tempKey, } from "./optimistic.js";
|
|
17
|
+
export { useAction, useKeyedAction } from "./use-action.js";
|
|
18
|
+
export { useOptimisticList, } from "./use-optimistic-list.js";
|
|
19
|
+
export { useOptimisticValue } from "./use-optimistic-value.js";
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ux/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAA4C,MAAM,eAAe,CAAC;AACpH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,SAAS,EACT,SAAS,EACT,OAAO,EACP,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,OAAO,GAIR,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAqD,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EACL,iBAAiB,GAIlB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAqD,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@connextar/house/ux/navigation` — feedback for moving between screens.
|
|
3
|
+
*
|
|
4
|
+
* Its own entry point because it is the only part of `ux` that imports `next`,
|
|
5
|
+
* which is an optional peer dependency: an app on another framework (or any
|
|
6
|
+
* app's Vitest suite running under plain Node) can still have the optimistic
|
|
7
|
+
* hooks from `@connextar/house/ux` without Next installed.
|
|
8
|
+
*/
|
|
9
|
+
export { BUSY_ATTRIBUTE, NavigationProgress, startNavigation, startRouteProgress, useAppRouter, useNavigate, } from "./navigation-progress.js";
|
|
10
|
+
//# sourceMappingURL=navigation-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-index.d.ts","sourceRoot":"","sources":["../../src/ux/navigation-index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@connextar/house/ux/navigation` — feedback for moving between screens.
|
|
3
|
+
*
|
|
4
|
+
* Its own entry point because it is the only part of `ux` that imports `next`,
|
|
5
|
+
* which is an optional peer dependency: an app on another framework (or any
|
|
6
|
+
* app's Vitest suite running under plain Node) can still have the optimistic
|
|
7
|
+
* hooks from `@connextar/house/ux` without Next installed.
|
|
8
|
+
*/
|
|
9
|
+
export { BUSY_ATTRIBUTE, NavigationProgress, startNavigation, startRouteProgress, useAppRouter, useNavigate, } from "./navigation-progress.js";
|
|
10
|
+
//# sourceMappingURL=navigation-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-index.js","sourceRoot":"","sources":["../../src/ux/navigation-index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/** The attribute every busy control carries, action or navigation alike. */
|
|
3
|
+
export declare const BUSY_ATTRIBUTE = "data-busy";
|
|
4
|
+
/**
|
|
5
|
+
* Show the navigation feedback for something this module cannot see on its
|
|
6
|
+
* own — a programmatic `router.push`. Pass the control that caused it and it
|
|
7
|
+
* gets the spinner too.
|
|
8
|
+
*/
|
|
9
|
+
export declare function startNavigation(element?: Element | null): void;
|
|
10
|
+
/** Backwards-compatible alias for the original name. */
|
|
11
|
+
export declare const startRouteProgress: typeof startNavigation;
|
|
12
|
+
/**
|
|
13
|
+
* `useRouter`, with the navigation feedback attached to `push` and `replace`.
|
|
14
|
+
*
|
|
15
|
+
* A click that runs `router.push(href)` is invisible to the watcher above —
|
|
16
|
+
* there is no anchor and no popstate — so those navigations were the ones with
|
|
17
|
+
* no feedback at all. The worst case is the one right after a save: the
|
|
18
|
+
* button's own spinner stops when the write lands, and then nothing happens
|
|
19
|
+
* for as long as the next screen takes to render.
|
|
20
|
+
*
|
|
21
|
+
* Swapping the import is the whole change; no call site moves. `refresh`,
|
|
22
|
+
* `back`, `forward` and `prefetch` pass straight through — a refresh re-renders
|
|
23
|
+
* the screen you are already on, which needs no bar.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useAppRouter(): {
|
|
26
|
+
push: (href: string, options?: import("next/dist/shared/lib/app-router-context.shared-runtime.js").NavigateOptions | undefined) => void;
|
|
27
|
+
replace: (href: string, options?: import("next/dist/shared/lib/app-router-context.shared-runtime.js").NavigateOptions | undefined) => void;
|
|
28
|
+
back(): void;
|
|
29
|
+
forward(): void;
|
|
30
|
+
refresh(): void;
|
|
31
|
+
prefetch(href: string, options?: import("next/dist/shared/lib/app-router-context.shared-runtime.js").PrefetchOptions): void;
|
|
32
|
+
experimental_gesturePush?(href: string, options?: import("next/dist/shared/lib/app-router-context.shared-runtime.js").NavigateOptions): void;
|
|
33
|
+
bfcacheId: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* `router.push` with the feedback attached, and the control that caused it
|
|
37
|
+
* marked as busy. For a button that navigates rather than saves.
|
|
38
|
+
*/
|
|
39
|
+
export declare function useNavigate(): (href: string, options?: {
|
|
40
|
+
replace?: boolean;
|
|
41
|
+
element?: Element | null;
|
|
42
|
+
}) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Mount once, above everything else — including anything that suspends, or the
|
|
45
|
+
* bar disappears for exactly the navigations it is there for.
|
|
46
|
+
*
|
|
47
|
+
* `className` styles the filled part of the bar, so the host app picks its own
|
|
48
|
+
* colour without this module knowing any of its tokens.
|
|
49
|
+
*/
|
|
50
|
+
export declare function NavigationProgress({ className }: {
|
|
51
|
+
className?: string;
|
|
52
|
+
}): React.JSX.Element;
|
|
53
|
+
//# sourceMappingURL=navigation-progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-progress.d.ts","sourceRoot":"","sources":["../../src/ux/navigation-progress.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgC/B,4EAA4E;AAC5E,eAAO,MAAM,cAAc,cAAc,CAAC;AAqB1C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAI9D;AAED,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,wBAAkB,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY;;;;;;;;;EAkB3B;AAED;;;GAGG;AACH,wBAAgB,WAAW,WAGhB,MAAM,YAAY;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,UAO3E;AA0ID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,qBAMvE"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { usePathname, useRouter, useSearchParams } from "next/navigation.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
/**
|
|
6
|
+
* Feedback for the other half of "nothing answers my click": moving between
|
|
7
|
+
* screens.
|
|
8
|
+
*
|
|
9
|
+
* Two signals, because they answer two different questions:
|
|
10
|
+
*
|
|
11
|
+
* - **A bar across the top of the page** — "something is happening". It waits
|
|
12
|
+
* a moment before appearing so a fast navigation does not flash it.
|
|
13
|
+
* - **A spinner on the thing that was clicked** — "*that* is what is
|
|
14
|
+
* happening". Without it, a slow route on a page full of links gives no clue
|
|
15
|
+
* which one took, which is when people click a second one.
|
|
16
|
+
*
|
|
17
|
+
* The second is set on the DOM node directly rather than through React state.
|
|
18
|
+
* The click can land on any link anywhere in the tree, including ones rendered
|
|
19
|
+
* by pages this component knows nothing about, and an attribute is the only
|
|
20
|
+
* thing they all have in common. `data-busy` is the same attribute the button
|
|
21
|
+
* primitive sets for an action, so one rule in the stylesheet covers both.
|
|
22
|
+
*/
|
|
23
|
+
/** Delay before the bar appears, so fast navigations do not flash it. */
|
|
24
|
+
const START_DELAY_MS = 140;
|
|
25
|
+
/** Cadence of the trickle that creeps the bar towards 90%. */
|
|
26
|
+
const TRICKLE_MS = 220;
|
|
27
|
+
/** Safety net: never leave the bar running forever if a navigation never commits. */
|
|
28
|
+
const MAX_PENDING_MS = 20_000;
|
|
29
|
+
/** How long the completed bar stays at 100% before fading out. */
|
|
30
|
+
const COMPLETE_MS = 260;
|
|
31
|
+
const START_EVENT = "cx:navigation-start";
|
|
32
|
+
/** The attribute every busy control carries, action or navigation alike. */
|
|
33
|
+
export const BUSY_ATTRIBUTE = "data-busy";
|
|
34
|
+
/** The control currently marked as the reason for a navigation. */
|
|
35
|
+
let marked = null;
|
|
36
|
+
function unmark() {
|
|
37
|
+
if (!marked)
|
|
38
|
+
return;
|
|
39
|
+
marked.removeAttribute(BUSY_ATTRIBUTE);
|
|
40
|
+
marked.removeAttribute("aria-busy");
|
|
41
|
+
marked = null;
|
|
42
|
+
}
|
|
43
|
+
function mark(element) {
|
|
44
|
+
if (marked === element)
|
|
45
|
+
return;
|
|
46
|
+
unmark();
|
|
47
|
+
if (!element)
|
|
48
|
+
return;
|
|
49
|
+
marked = element;
|
|
50
|
+
element.setAttribute(BUSY_ATTRIBUTE, "true");
|
|
51
|
+
element.setAttribute("aria-busy", "true");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Show the navigation feedback for something this module cannot see on its
|
|
55
|
+
* own — a programmatic `router.push`. Pass the control that caused it and it
|
|
56
|
+
* gets the spinner too.
|
|
57
|
+
*/
|
|
58
|
+
export function startNavigation(element) {
|
|
59
|
+
if (typeof window === "undefined")
|
|
60
|
+
return;
|
|
61
|
+
mark(element ?? null);
|
|
62
|
+
window.dispatchEvent(new Event(START_EVENT));
|
|
63
|
+
}
|
|
64
|
+
/** Backwards-compatible alias for the original name. */
|
|
65
|
+
export const startRouteProgress = startNavigation;
|
|
66
|
+
/**
|
|
67
|
+
* `useRouter`, with the navigation feedback attached to `push` and `replace`.
|
|
68
|
+
*
|
|
69
|
+
* A click that runs `router.push(href)` is invisible to the watcher above —
|
|
70
|
+
* there is no anchor and no popstate — so those navigations were the ones with
|
|
71
|
+
* no feedback at all. The worst case is the one right after a save: the
|
|
72
|
+
* button's own spinner stops when the write lands, and then nothing happens
|
|
73
|
+
* for as long as the next screen takes to render.
|
|
74
|
+
*
|
|
75
|
+
* Swapping the import is the whole change; no call site moves. `refresh`,
|
|
76
|
+
* `back`, `forward` and `prefetch` pass straight through — a refresh re-renders
|
|
77
|
+
* the screen you are already on, which needs no bar.
|
|
78
|
+
*/
|
|
79
|
+
export function useAppRouter() {
|
|
80
|
+
const router = useRouter();
|
|
81
|
+
return React.useMemo(() => ({
|
|
82
|
+
...router,
|
|
83
|
+
// Forwarded by spread, not by naming the options: passing an explicit
|
|
84
|
+
// `undefined` is a different call from passing nothing.
|
|
85
|
+
push: (...args) => {
|
|
86
|
+
startNavigation();
|
|
87
|
+
router.push(...args);
|
|
88
|
+
},
|
|
89
|
+
replace: (...args) => {
|
|
90
|
+
startNavigation();
|
|
91
|
+
router.replace(...args);
|
|
92
|
+
},
|
|
93
|
+
}), [router]);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* `router.push` with the feedback attached, and the control that caused it
|
|
97
|
+
* marked as busy. For a button that navigates rather than saves.
|
|
98
|
+
*/
|
|
99
|
+
export function useNavigate() {
|
|
100
|
+
const router = useRouter();
|
|
101
|
+
return React.useCallback((href, options) => {
|
|
102
|
+
startNavigation(options?.element ?? null);
|
|
103
|
+
if (options?.replace)
|
|
104
|
+
router.replace(href);
|
|
105
|
+
else
|
|
106
|
+
router.push(href);
|
|
107
|
+
}, [router]);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A click that means "take me there", rather than one the browser will handle
|
|
111
|
+
* itself — a new tab, a download, a context menu.
|
|
112
|
+
*
|
|
113
|
+
* Deliberately *not* a `defaultPrevented` check. This runs in the capture
|
|
114
|
+
* phase, and the reason is the whole point of this listener: Next's `Link`
|
|
115
|
+
* calls `preventDefault()` on its way to a client-side navigation, so by the
|
|
116
|
+
* time a bubble-phase listener sees the click, every in-app link looks
|
|
117
|
+
* cancelled. Guarding on `defaultPrevented` there means the bar fires for
|
|
118
|
+
* exactly the navigations that do not need it and stays silent for all the
|
|
119
|
+
* ones that do — which is what was happening here until this was measured in
|
|
120
|
+
* the browser.
|
|
121
|
+
*/
|
|
122
|
+
function isPlainLeftClick(event) {
|
|
123
|
+
return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
|
124
|
+
}
|
|
125
|
+
function navigatesElsewhere(url) {
|
|
126
|
+
if (url.origin !== window.location.origin)
|
|
127
|
+
return false;
|
|
128
|
+
// API routes are downloads/exports, not page navigations.
|
|
129
|
+
if (url.pathname.startsWith("/api/"))
|
|
130
|
+
return false;
|
|
131
|
+
return url.pathname !== window.location.pathname || url.search !== window.location.search;
|
|
132
|
+
}
|
|
133
|
+
function NavigationProgressBar({ className }) {
|
|
134
|
+
const pathname = usePathname();
|
|
135
|
+
const search = useSearchParams().toString();
|
|
136
|
+
const [progress, setProgress] = React.useState(null);
|
|
137
|
+
const timers = React.useRef([]);
|
|
138
|
+
const active = React.useRef(false);
|
|
139
|
+
const clearTimers = React.useCallback(() => {
|
|
140
|
+
timers.current.forEach((id) => window.clearTimeout(id));
|
|
141
|
+
timers.current = [];
|
|
142
|
+
}, []);
|
|
143
|
+
const stop = React.useCallback(() => {
|
|
144
|
+
clearTimers();
|
|
145
|
+
active.current = false;
|
|
146
|
+
delete document.body.dataset.routePending;
|
|
147
|
+
unmark();
|
|
148
|
+
setProgress((value) => (value === null ? null : 100));
|
|
149
|
+
window.setTimeout(() => {
|
|
150
|
+
// A new navigation may have started in the meantime; leave its bar alone.
|
|
151
|
+
if (!active.current)
|
|
152
|
+
setProgress(null);
|
|
153
|
+
}, COMPLETE_MS);
|
|
154
|
+
}, [clearTimers]);
|
|
155
|
+
const start = React.useCallback(() => {
|
|
156
|
+
if (active.current)
|
|
157
|
+
return;
|
|
158
|
+
active.current = true;
|
|
159
|
+
document.body.dataset.routePending = "true";
|
|
160
|
+
const trickle = () => {
|
|
161
|
+
setProgress((value) => (value === null ? value : Math.min(value + Math.max(1, (90 - value) * 0.16), 90)));
|
|
162
|
+
timers.current.push(window.setTimeout(trickle, TRICKLE_MS));
|
|
163
|
+
};
|
|
164
|
+
timers.current.push(window.setTimeout(() => {
|
|
165
|
+
setProgress(8);
|
|
166
|
+
trickle();
|
|
167
|
+
}, START_DELAY_MS));
|
|
168
|
+
timers.current.push(window.setTimeout(stop, MAX_PENDING_MS));
|
|
169
|
+
}, [stop]);
|
|
170
|
+
// The navigation committed once the URL the router reports has changed.
|
|
171
|
+
const initialRender = React.useRef(true);
|
|
172
|
+
React.useEffect(() => {
|
|
173
|
+
if (initialRender.current) {
|
|
174
|
+
initialRender.current = false;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
stop();
|
|
178
|
+
}, [pathname, search, stop]);
|
|
179
|
+
React.useEffect(() => {
|
|
180
|
+
const onClick = (event) => {
|
|
181
|
+
if (!isPlainLeftClick(event))
|
|
182
|
+
return;
|
|
183
|
+
const target = event.target;
|
|
184
|
+
if (!(target instanceof Element))
|
|
185
|
+
return;
|
|
186
|
+
const anchor = target.closest("a");
|
|
187
|
+
if (!anchor?.href || anchor.hasAttribute("download"))
|
|
188
|
+
return;
|
|
189
|
+
if (anchor.target && anchor.target !== "_self")
|
|
190
|
+
return;
|
|
191
|
+
if (!navigatesElsewhere(new URL(anchor.href)))
|
|
192
|
+
return;
|
|
193
|
+
// Mark before `start`, which returns early when a navigation is already
|
|
194
|
+
// running: a second click during a slow load should still move the
|
|
195
|
+
// spinner to the link that was actually clicked.
|
|
196
|
+
mark(anchor);
|
|
197
|
+
start();
|
|
198
|
+
};
|
|
199
|
+
const onSubmit = (event) => {
|
|
200
|
+
if (event.defaultPrevented)
|
|
201
|
+
return;
|
|
202
|
+
const form = event.target;
|
|
203
|
+
if (!(form instanceof HTMLFormElement))
|
|
204
|
+
return;
|
|
205
|
+
if (form.method.toLowerCase() !== "get" || !form.action)
|
|
206
|
+
return;
|
|
207
|
+
if (new URL(form.action).origin !== window.location.origin)
|
|
208
|
+
return;
|
|
209
|
+
if (event.submitter)
|
|
210
|
+
mark(event.submitter);
|
|
211
|
+
start();
|
|
212
|
+
};
|
|
213
|
+
// Capture, so this runs before `Link` cancels the click (see above). The
|
|
214
|
+
// submit listener stays in the bubble phase on purpose: a form with an
|
|
215
|
+
// `onSubmit` that saves rather than navigates is the common case here, and
|
|
216
|
+
// `defaultPrevented` is exactly how to tell those apart.
|
|
217
|
+
document.addEventListener("click", onClick, true);
|
|
218
|
+
document.addEventListener("submit", onSubmit);
|
|
219
|
+
window.addEventListener("popstate", start);
|
|
220
|
+
window.addEventListener(START_EVENT, start);
|
|
221
|
+
return () => {
|
|
222
|
+
document.removeEventListener("click", onClick, true);
|
|
223
|
+
document.removeEventListener("submit", onSubmit);
|
|
224
|
+
window.removeEventListener("popstate", start);
|
|
225
|
+
window.removeEventListener(START_EVENT, start);
|
|
226
|
+
clearTimers();
|
|
227
|
+
unmark();
|
|
228
|
+
delete document.body.dataset.routePending;
|
|
229
|
+
};
|
|
230
|
+
}, [clearTimers, start]);
|
|
231
|
+
if (progress === null)
|
|
232
|
+
return null;
|
|
233
|
+
return (_jsx("div", { className: "pointer-events-none fixed inset-x-0 top-0 z-[100] h-0.5", role: "progressbar", "aria-label": "Loading page", "aria-busy": "true", children: _jsx("div", { className: className, style: { width: `${progress}%`, opacity: progress === 100 ? 0 : 1 } }) }));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Mount once, above everything else — including anything that suspends, or the
|
|
237
|
+
* bar disappears for exactly the navigations it is there for.
|
|
238
|
+
*
|
|
239
|
+
* `className` styles the filled part of the bar, so the host app picks its own
|
|
240
|
+
* colour without this module knowing any of its tokens.
|
|
241
|
+
*/
|
|
242
|
+
export function NavigationProgress({ className }) {
|
|
243
|
+
return (_jsx(React.Suspense, { fallback: null, children: _jsx(NavigationProgressBar, { className: className }) }));
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=navigation-progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-progress.js","sourceRoot":"","sources":["../../src/ux/navigation-progress.tsx"],"names":[],"mappings":"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"}
|