Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
179 commits
Select commit Hold shift + click to select a range
b7d78ae
feat(core): add composable read-only restrictions
nperez0111 Sep 15, 2026
72a1702
feat(core)!: refine attribution colors and deleted-block styling
nperez0111 Sep 15, 2026
621902e
refactor(core)!: unify versioning state and preview lifecycle
nperez0111 Sep 15, 2026
11b4d59
feat(react)!: rebuild the version history sidebar
nperez0111 Sep 15, 2026
9be8d14
chore(examples): refresh versioning demos and setup
nperez0111 Sep 15, 2026
f2857ad
Improve versioning sidebar menu customization
nperez0111 Sep 15, 2026
f8ecfc9
Polish suggestion gallery styling and expand versioning coverage
nperez0111 Sep 15, 2026
194f69f
Fix build and snapshot runner dependency conflicts
nperez0111 Sep 15, 2026
48bec82
Fix version history seeding retries and preview state
nperez0111 Sep 15, 2026
a82f062
refactor: unify editability in ReadOnly extension
nperez0111 Sep 15, 2026
9cb2b5b
fix: animate versioning highlights without DOM mutations
nperez0111 Sep 16, 2026
b60ac63
Upgrade Yjs and y-prosemirror
nperez0111 Sep 16, 2026
2f9b255
Add attribution for block property changes
nperez0111 Sep 16, 2026
e4a5779
Improve version history keyboard accessibility and remove Save action
nperez0111 Sep 16, 2026
459b4db
Refactor YHub versioning and add safe history refresh
nperez0111 Sep 16, 2026
10062b6
Fix YHub attribution bounds for current version previews
nperez0111 Sep 16, 2026
449b9c5
Require synchronous version previews and simplify adapter contracts
nperez0111 Sep 16, 2026
e754cb6
Keep version selection visible when deletion clears a name
nperez0111 Sep 16, 2026
72fd1e5
Share versioning UI primitives and simplify sidebar state
nperez0111 Sep 16, 2026
c7fe526
Deduplicate versioning example history fixtures
nperez0111 Sep 16, 2026
afec519
refactor(react): move versioning to a dedicated sub-export
nperez0111 Sep 16, 2026
c9bc61b
fix: use read-only
nperez0111 Sep 16, 2026
6105796
chore: yjs versions
nperez0111 Sep 16, 2026
e537940
refactor: simplify
nperez0111 Sep 16, 2026
4dd8c83
refactor: inline version history sidebar, default editable true, use …
nperez0111 Sep 16, 2026
6939146
refactor: simplify scrollToFirstChange
nperez0111 Sep 16, 2026
26312d6
refactor: i18n versionLabel via blocknote dictionary
nperez0111 Sep 16, 2026
60fbd84
fix(core): report ReadOnly state from isEditable while unmounted
nperez0111 Sep 16, 2026
c492792
refactor(react): fixed header over scrolling version list, drop focus…
nperez0111 Sep 16, 2026
2f583c7
fix(react): return to Current when deleted version leaves the list
nperez0111 Sep 16, 2026
4a26842
chore: rm
nperez0111 Sep 16, 2026
8aa535a
fix(react): dedupe generic formatting-change tooltip label
nperez0111 Sep 16, 2026
ad01251
docs(gallery): mark textcolor-vs-bgcolor prop attribution as resolved
nperez0111 Sep 16, 2026
b93aa89
fix(core): stable empty-doc binding in new y/ collab stack
nperez0111 Sep 16, 2026
ba4e246
refactor(core): split y snapshot preview into codec + render modules
nperez0111 Sep 17, 2026
f96a8a6
refactor(core): drop yhub restore refresh delay, guard empty doc
nperez0111 Sep 17, 2026
1ce3379
refactor(core): rework Versioning list/preview sessions, add sub-modu…
nperez0111 Sep 17, 2026
44ffe1c
fix(core): flatten legacy anonymous text nodes when diffing snapshots
nperez0111 Sep 17, 2026
15ec810
test(e2e): refresh snapshots for pristine empty docs and trailing block
nperez0111 Sep 17, 2026
3c5ee8a
refactor(core): render version diffs without clearing the document
nperez0111 Sep 17, 2026
b29be57
refactor(versioning): derive loading state instead of storing it
nperez0111 Sep 17, 2026
ae21c0b
refactor(core): render version diffs via patched @y/prosemirror fragm…
nperez0111 Sep 17, 2026
bffcb7a
refactor(core): gate empty-doc sync via initialContentCompare instead…
nperez0111 Sep 18, 2026
32463db
fix(core): re-anchor initial-content gate when the empty skeleton is …
nperez0111 Sep 18, 2026
a38ba03
fix(tests): isPristineEmptyEditor ignores skeleton block ids
nperez0111 Sep 18, 2026
e2d5fbc
refactor(versioning): remove unused review leftovers and clarify refs
nperez0111 Sep 21, 2026
784de3a
fix(core): update YHub activity grouping API
nperez0111 Sep 21, 2026
46605aa
feat(versioning): refine sidebar skins and naming
nperez0111 Sep 21, 2026
32197f9
fix(core): reconcile version preview attribution
nperez0111 Sep 22, 2026
43e2f6f
Merge remote-tracking branch 'origin/feat/versioning-sidebar-ux-b' in…
nperez0111 Sep 22, 2026
2170aa7
Merge remote-tracking branch 'origin/main' into feat/versioning-sideb…
nperez0111 Sep 22, 2026
85734d9
fix: stabilize experimental yjs13 versioning
nperez0111 Sep 22, 2026
10082b8
docs(examples): restore unresolved suggestion feedback
nperez0111 Sep 22, 2026
206d4be
fix(examples): wire suggestion multi-editor mode
nperez0111 Sep 22, 2026
fa085bd
test(react): colocate browser UI tests
nperez0111 Sep 22, 2026
155d256
fix(versioning): localize version labels
nperez0111 Sep 22, 2026
616f23a
fix(versioning): keep sidebar menus visible
nperez0111 Sep 23, 2026
60a6a3a
Merge remote-tracking branch 'origin/main' into feat/versioning-sideb…
nperez0111 Sep 23, 2026
7db8d83
refactor(react): simplify attribution tooltip reference
nperez0111 Sep 23, 2026
57020b3
chore: remove y-prosemirror patch
nperez0111 Sep 23, 2026
ca3de6a
test: update concurrent formatting snapshot
nperez0111 Sep 23, 2026
12d669c
fix(react): forward client rects to floating references
nperez0111 Sep 23, 2026
bb83965
fix(collaboration): preserve sync across editor remounts
nperez0111 Sep 24, 2026
3ff2fa3
fix(versioning): keep in-memory checkpoint current until edit
nperez0111 Sep 24, 2026
0d62219
fix(versioning): theme externally portaled sidebar
nperez0111 Sep 24, 2026
33a4f5e
feat(versioning): support Yjs 13 snapshot restore
nperez0111 Sep 24, 2026
fc7fda1
fix(versioning): tolerate attribution fetch failures
nperez0111 Sep 25, 2026
6f08421
fix(core): remove unused loader selector
nperez0111 Sep 25, 2026
0a489b5
chore: upgrade @y/prosemirror and remove patch
nperez0111 Sep 25, 2026
5021fd0
Merge branch 'main' of github.com:TypeCellOS/BlockNote into feat/vers…
nperez0111 Sep 25, 2026
d3b9cf5
test: cover legacy Yjs document binding compatibility
nperez0111 Sep 25, 2026
0682856
chore: upgrade lib0 to 1.0.0-rc.33
nperez0111 Sep 25, 2026
2e8bf07
Merge branch 'add-legacy-yjs-doc-binding-test' into feat/versioning-s…
nperez0111 Sep 25, 2026
ce541df
chore(playground): remove y-prosemirror optimizer exclusion
nperez0111 Sep 25, 2026
07a833a
Remove compare since beginning version action
nperez0111 Sep 28, 2026
225d57c
Normalize version comparison order in sidebar
nperez0111 Sep 28, 2026
be2fcfb
Fix attribution tooltips for source-backed diff previews
nperez0111 Sep 28, 2026
019d1f1
chore: retrigger PR preview package build
nperez0111 Sep 28, 2026
6147acf
Merge main into versioning sidebar branch
nperez0111 Sep 28, 2026
47fe3fb
fix(math): update selected inline content styling (#2983)
matthewlipski Sep 28, 2026
f4d4991
feat: Down arrow in block without content at end of doc creates parag…
matthewlipski Sep 28, 2026
4c2828f
chore: update lib0 version
nperez0111 Sep 28, 2026
e1dc6bb
fix: `insertInlineContent` adding content after cursor (BLO-1356) (#3…
matthewlipski Sep 28, 2026
ce406d8
ci(deps): bump voidzero-dev/setup-vp from 1.20.0 to 1.21.1 (#3141)
dependabot[bot] Sep 29, 2026
d96013e
feat: Update backspace handling in nested blocks (BLO-1326) (#3124)
matthewlipski Sep 30, 2026
adbede8
chore: upgrade Yjs 13 and 14 dependencies
nperez0111 Sep 30, 2026
664aab7
chore(deps): update @y/prosemirror and lib0 prereleases
nperez0111 Oct 2, 2026
d87fd62
feat: use native YHub versions with typed metadata
nperez0111 Oct 2, 2026
cc63dad
fix: isolate version previews from undo history
nperez0111 Oct 2, 2026
e463df3
Merge remote-tracking branch 'origin/main' into feat/versioning-sideb…
nperez0111 Oct 2, 2026
154e925
Match multi-doc history sidebar to the example theme
nperez0111 Oct 2, 2026
326f1f6
fix: clean up REST thread store test editor
nperez0111 Oct 2, 2026
f833032
fix: handle version history fetch failures with typed results
nperez0111 Oct 5, 2026
fb29f1f
fix: use partial document fixture in suggestion gallery
nperez0111 Oct 5, 2026
f175543
chore: update suggestion gallery table issue statuses
nperez0111 Oct 5, 2026
89c1253
refactor(react): render sidebars into app layouts with RenderInPortal…
YousefED Oct 5, 2026
0708896
chore(examples): regenerate example data
YousefED Oct 5, 2026
12a81e6
Fix runtime extension lifecycle and Yjs fork state isolation
nperez0111 Oct 5, 2026
18ffca9
Fix version attribution tooltips and unnamed snapshot labels
nperez0111 Oct 5, 2026
ef4015d
Merge remote-tracking branch 'origin/feat/versioning-sidebar-ux-b' in…
nperez0111 Oct 5, 2026
6863e9a
refactor: simplify previewing of version history
nperez0111 Oct 5, 2026
9eb1b06
refactor(core): expose built-in extensions only through extensions en…
nperez0111 Oct 6, 2026
5c033cb
fix(build): refresh cached declarations and support custom-schema ver…
nperez0111 Oct 6, 2026
98eac12
refactor(versioning): distinguish backends and accept JSON history seeds
nperez0111 Oct 6, 2026
cd9808c
chore: lint
nperez0111 Oct 6, 2026
55c872a
feat(core): expose editor destroy event
nperez0111 Oct 6, 2026
01e7fdb
fix(core): enable undo and redo for Yjs v14 collaboration
nperez0111 Oct 6, 2026
c1e2f51
fix(versioning): format version dates with one locale-aware formatter
YousefED Oct 6, 2026
903b460
fix: keep version snapshot renames visible while saving
nperez0111 Oct 6, 2026
a2d830e
fix(core): retain menu helpers in root exports
nperez0111 Oct 6, 2026
8cfb79a
fix: allow version naming without switching comparison
nperez0111 Oct 6, 2026
58079f7
fix(core): preserve code and audio rendering in version comparisons
nperez0111 Oct 6, 2026
1c1be9f
fix(tests): refresh deleted code block baselines and Docker build
nperez0111 Oct 6, 2026
04fd335
fix(build): isolate package declaration writes
nperez0111 Oct 6, 2026
087ef08
fix(versioning): name only the kind of change in version diff tooltips
YousefED Oct 6, 2026
6514154
fix(versioning): handle provider failures and simplify sidebar actions
nperez0111 Oct 6, 2026
efae099
fix(versioning): use latest YHub checkpoint as current
nperez0111 Oct 6, 2026
045f94b
fix(core): render previews from the newer source in diffs and suggest…
YousefED Oct 6, 2026
ba40c2b
docs(core): flag plain content filtering for suggestion mode
nperez0111 Oct 6, 2026
7567884
Merge pull request #3157 from TypeCellOS/fix/preview-hidden-source-diff
nperez0111 Oct 6, 2026
cd6e9aa
fix(core): use ProseMirror history for Yjs v14 collaboration
nperez0111 Oct 6, 2026
bcd6a21
Merge remote-tracking branch 'origin/main' into feat/versioning-sideb…
nperez0111 Oct 6, 2026
b5c2ed3
fix(build): emit package declarations reliably
nperez0111 Oct 6, 2026
12432ac
fix(react): restore versioning build entry
nperez0111 Oct 6, 2026
27eb966
fix(versioning): restore immediate snapshot loading indicator
nperez0111 Oct 7, 2026
01823b0
fix: preserve versioning locks and clear failed sidebar actions
nperez0111 Oct 7, 2026
1febdd8
fix: clean up type-aware lint warnings
nperez0111 Oct 7, 2026
bdf3727
test(comments): stabilize reaction picker interactions
nperez0111 Oct 7, 2026
f3a2791
fix(versioning): address sidebar focus, comparison, and history bugs
nperez0111 Oct 7, 2026
574f30e
fix(versioning): exclude previews from undo history
nperez0111 Oct 7, 2026
ec5d6de
fix: refresh column resize state after document edits
nperez0111 Oct 7, 2026
3fa5dc5
feat: compare document versions from the beginning
nperez0111 Oct 7, 2026
f45af91
feat: add paginated version history
nperez0111 Oct 7, 2026
4a5308b
feat: load older versions on scroll
nperez0111 Oct 7, 2026
8d235ba
chore: remove unused versioning translations and redundant docs
nperez0111 Oct 7, 2026
23143cb
test(versioning): add tests for version diff attribution and nesting …
YousefED Oct 8, 2026
c5e9676
test(versioning): add tests for type changes and moves in version diffs
YousefED Oct 8, 2026
823efc1
fix: include first edits in version comparisons
nperez0111 Oct 8, 2026
d31c6b7
feat: support opt-in Yjs 13 version comparisons
nperez0111 Oct 8, 2026
08f303d
fix: compare in-memory versions against saved content
nperez0111 Oct 8, 2026
4125870
test(versioning): point the old-binding tests at #3173
YousefED Oct 8, 2026
48f141b
test(versioning): expect content deleted with its block under the blo…
YousefED Oct 8, 2026
1e2f462
test(versioning): expect a block moved elsewhere at both places
YousefED Oct 8, 2026
ec48c51
test(gallery): one note per scenario for blocks re-created by a change
YousefED Oct 8, 2026
c711edd
test(versioning): compare an old-binding table resize cell by cell
YousefED Oct 8, 2026
388b886
test(gallery): note the re-created blocks of a concurrent indent
YousefED Oct 8, 2026
d8c37e3
test(versioning): credit a child lost with its parent to the parent's…
YousefED Oct 8, 2026
e1aad22
test(gallery): red for a diff that credits the wrong user, yellow for…
YousefED Oct 8, 2026
8004961
test(gallery): a lost change inside a deleted block is expected; Ente…
YousefED Oct 8, 2026
926f3eb
test(gallery): add a scenario where text typed into a concurrently de…
YousefED Oct 8, 2026
5ad3379
test(versioning): an old-binding diff leaves the document unchanged a…
YousefED Oct 8, 2026
89d9f9d
test(gallery): text typed into a concurrently deleted block is in nei…
YousefED Oct 8, 2026
dd5b532
test(versioning): cover twice-copied blocks, moved children, lost con…
YousefED Oct 8, 2026
902781a
test(versioning): credit every word to its writer between any two ver…
YousefED Oct 9, 2026
fd165dd
fix(versioning): compare a version only to the end of the previous one
YousefED Oct 9, 2026
220164a
fix(versioning): name every change in a version diff, and hide block …
YousefED Oct 9, 2026
bc1f59b
test(versioning): point the re-created block markers to #3166
YousefED Oct 9, 2026
a4c4eef
fix(versioning): name only the authors of the attribute changes shown
YousefED Oct 9, 2026
64488b4
fix(versioning): make the start of the document an empty row
YousefED Oct 9, 2026
ab8d2f9
fix(versioning): diff structural changes made by the old Yjs binding
YousefED Oct 8, 2026
ccd46e0
fix(collaboration): stop replacing tables that one edit reshapes both…
YousefED Oct 8, 2026
a591844
fix(versioning): credit an old-binding structural change only to whoe…
YousefED Oct 8, 2026
a7e23b9
fix(versioning): credit text typed after an old-binding structural ch…
YousefED Oct 9, 2026
6ce4322
fix(versioning): don't attribute lost content to whoever removed it (…
YousefED Oct 8, 2026
bfa68e8
feat(gallery): toggle the experimental version diff flags
YousefED Oct 8, 2026
1bbbacb
fix(versioning): show content deleted with its block under the block'…
YousefED Oct 8, 2026
c16997f
fix(versioning): keep the other deleters of a lost move
YousefED Oct 8, 2026
46c9fb5
refactor(versioning): one option for the experimental version diff fixes
YousefED Oct 8, 2026
c5c2bbb
feat(versioning): show copied blocks once in version diffs (experimen…
YousefED Oct 8, 2026
ada5d5c
fix(versioning): pair a block copied twice with the block of the earl…
YousefED Oct 8, 2026
d7d51b2
fix(versioning): credit text across a block re-created several times
YousefED Oct 9, 2026
f020edb
fix(versioning): credit text typed into the last copy to its writer
YousefED Oct 9, 2026
2ef45e6
fix(versioning): name no author for a move whose copy was gc'd
YousefED Oct 9, 2026
c6ddbc3
test(versioning): open the start row's menu without its name item
YousefED Oct 9, 2026
a0f7667
Merge remote-tracking branch 'origin/main' into restack/3090
YousefED Oct 9, 2026
6d611a5
Merge branch 'restack/3090' into restack/3167
YousefED Oct 9, 2026
3b7d4ec
Merge branch 'restack/3167' into restack/block-copies
YousefED Oct 9, 2026
83153fd
Merge branch 'main' into fix/version-diff-cascade-attribution
YousefED Oct 15, 2026
05cc9ba
docs(gallery): show the experimental attribution of two lost-content …
YousefED Oct 15, 2026
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
137 changes: 124 additions & 13 deletions examples/07-collaboration/14-suggestion-gallery/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import "./style.css";
import type { GalleryEditor } from "./gallerySchema";
import {
createYVersionView,
type ExperimentalVersionDiffs,
type VersionDiffFixes,
versionDiffFixesIncluded,
SuggestionsExtension,
withCollaboration,
} from "@blocknote/core/y";
Expand All @@ -22,10 +25,64 @@ import {
createVersionMerge,
docFromBlocks,
} from "./scenarioDocs";
import { scenarios, SuggestionScenario } from "./scenarios";
import { Feedback, scenarios, SuggestionScenario } from "./scenarios";

type Mode = "suggestions" | "versioning";

// The experimental version diff fixes the Diff can show, none by default as
// in the editor. Kept in the URL, so a link opens the same view.
const FIXES: { value: VersionDiffFixes | undefined; label: string }[] = [
{ value: undefined, label: "Default" },
{ value: "implicitDeleteAttribution", label: "Implicit delete attribution" },
{
value: "implicitDeleteAttributionAndRecreatedBlocks",
label: "+ re-created blocks",
},
];
const ALL_FIXES: ExperimentalVersionDiffs = {
versionDiffFixes: FIXES[FIXES.length - 1].value,
};

function readFixes(): ExperimentalVersionDiffs {
const value = new URLSearchParams(window.location.search).get(
"versionDiffFixes",
);
return {
versionDiffFixes: FIXES.find((fixes) => fixes.value === value)?.value,
};
}

function writeFixes(experimental: ExperimentalVersionDiffs) {
const url = new URL(window.location.href);
if (experimental.versionDiffFixes) {
url.searchParams.set("versionDiffFixes", experimental.versionDiffFixes);
} else {
url.searchParams.delete("versionDiffFixes");
}
window.history.replaceState(null, "", url);
}

// A note with `when` describes the Diff with or without those fixes, so it
// only shows in Versioning mode when they match.
function applies(
f: Feedback,
mode: Mode,
experimental: ExperimentalVersionDiffs,
): boolean {
if (!f.when) {
return true;
}
const included = experimental.versionDiffFixes
? versionDiffFixesIncluded[experimental.versionDiffFixes]
: [];
return (
mode === "versioning" &&
Object.entries(f.when).every(
([fix, on]) => included.some((each) => each === fix) === on,
)
);
}

function makeAwareness(doc: Y.Doc, name: string, color: string): Awareness {
const awareness = new Awareness(doc);
awareness.setLocalStateField("user", { name, color });
Expand Down Expand Up @@ -333,7 +390,13 @@ function versioningUsers(scenario: SuggestionScenario): VersioningUser[] {
* editing any user re-merges (and re-diffs); editing Version 1 resets every user
* back to a fresh clone (via the `nonce` remount).
*/
function VersioningView({ scenario }: { scenario: SuggestionScenario }) {
function VersioningView({
scenario,
experimental,
}: {
scenario: SuggestionScenario;
experimental: ExperimentalVersionDiffs;
}) {
const [setup] = useState(() => {
const beforeDoc = docFromBlocks(scenario.initial);
return {
Expand Down Expand Up @@ -375,6 +438,7 @@ function VersioningView({ scenario }: { scenario: SuggestionScenario }) {
beforeDoc={setup.beforeDoc}
users={setup.users}
applyInitial={nonce === 0}
experimental={experimental}
/>
</div>
);
Expand All @@ -390,10 +454,12 @@ function VersionMerge({
beforeDoc,
users,
applyInitial,
experimental,
}: {
beforeDoc: Y.Doc;
users: VersioningUser[];
applyInitial: boolean;
experimental: ExperimentalVersionDiffs;
}) {
const [setup] = useState(() => {
// Records which user authored each merged change, so the Diff can color
Expand All @@ -415,6 +481,7 @@ function VersionMerge({
fragment: setup.afterDoc.get("doc"),
provider: { awareness: setup.diffAwareness },
user: USER_A,
experimental,
},
}),
);
Expand Down Expand Up @@ -531,8 +598,10 @@ const SEVERITY = {

// The most-severe note across a scenario's feedback — a known crash counts as
// high — or null if it has none. Drives the sidebar indicator.
function topSeverity(s: SuggestionScenario): "high" | "low" | "info" | null {
const fb = s.feedback ?? [];
function topSeverity(
s: SuggestionScenario,
fb: Feedback[],
): "high" | "low" | "info" | null {
if (s.knownCrash || fb.some((f) => f.severity === "high")) {
return "high";
}
Expand All @@ -542,15 +611,38 @@ function topSeverity(s: SuggestionScenario): "high" | "low" | "info" | null {
return fb.some((f) => f.severity === "info") ? "info" : null;
}

function severityBadge(s: SuggestionScenario): string {
const sev = topSeverity(s);
return sev ? SEVERITY[sev].icon + " " : "";
function notesFor(
s: SuggestionScenario,
mode: Mode,
experimental: ExperimentalVersionDiffs,
): Feedback[] {
return (s.feedback ?? []).filter((f) => applies(f, mode, experimental));
}

// The severity without fixes (the default) and, for a scenario the fixes
// affect, in parentheses the severity with all of them (green: no issue left).
// The chosen fixes don't change it.
function severityBadge(s: SuggestionScenario, mode: Mode): string {
const sev = topSeverity(s, notesFor(s, mode, {}));
let badge = sev ? SEVERITY[sev].icon + " " : "";
if (mode === "versioning" && s.feedback?.some((f) => f.when)) {
const best = topSeverity(s, notesFor(s, mode, ALL_FIXES));
badge += `(${best === "high" || best === "low" ? SEVERITY[best].icon : "🟢"}) `;
}
return badge;
}

export default function App() {
const [selectedId, setSelectedId] = useState(scenarios[0].id);
const [mode, setMode] = useState<Mode>("versioning");
const [experimental, setExperimental] = useState(readFixes);
const selected = scenarios.find((s) => s.id === selectedId)!;
const feedback = notesFor(selected, mode, experimental);

function choose(next: ExperimentalVersionDiffs) {
writeFixes(next);
setExperimental(next);
}

const categories = [...new Set(scenarios.map((s) => s.category))];

Expand All @@ -573,7 +665,7 @@ export default function App() {
}
onClick={() => setSelectedId(s.id)}
>
{severityBadge(s)}
{severityBadge(s, mode)}
{s.kind === "concurrent" ? "👥 " : ""}
{s.title}
</button>
Expand Down Expand Up @@ -605,14 +697,31 @@ export default function App() {
</div>
</div>

{selected.feedback && selected.feedback.length > 0 && (
{mode === "versioning" && (
<div className="bn-gallery-experiments">
Experimental fixes:
{FIXES.map(({ value, label }) => (
<label key={label}>
<input
type="radio"
name="versionDiffFixes"
checked={experimental.versionDiffFixes === value}
onChange={() => choose({ versionDiffFixes: value })}
/>
{label}
</label>
))}
</div>
)}

{feedback.length > 0 && (
<div className="bn-gallery-feedback">
<div className="bn-gallery-feedback-title">
{selected.feedback.some((f) => f.severity !== "info")
{feedback.some((f) => f.severity !== "info")
? "Known issues"
: "Notes"}
</div>
{[...selected.feedback]
{[...feedback]
.sort(
(a, b) => SEVERITY[a.severity].rank - SEVERITY[b.severity].rank,
)
Expand All @@ -630,9 +739,11 @@ export default function App() {
</div>
)}

<ScenarioErrorBoundary key={`${mode}:${selected.id}`}>
<ScenarioErrorBoundary
key={`${mode}:${selected.id}:${JSON.stringify(experimental)}`}
>
{mode === "versioning" ? (
<VersioningView scenario={selected} />
<VersioningView scenario={selected} experimental={experimental} />
) : (
<SuggestionsView scenario={selected} />
)}
Expand Down
Loading
Loading