@nkzw/codiff-core 1.9.0 → 1.9.1

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.
@@ -32,10 +32,11 @@ export type ReviewSurfaceProps = {
32
32
  onDeleteShare?: () => Promise<void> | void;
33
33
  onModeChange?: (mode: ReviewMode) => void;
34
34
  providerLabel?: string;
35
+ repositoryUrl?: string;
35
36
  settingsBar?: ReactNode;
36
37
  signInLabel?: string;
37
38
  snapshot: SharedWalkthroughSnapshot;
38
39
  sourceDescriptionFooterAside?: ReactNode;
39
40
  title?: string;
40
41
  };
41
- export declare function ReviewSurface({ commenting, externalUrl, gitIdentity, initialMode, interactive, onDeleteShare, onModeChange, providerLabel, settingsBar, signInLabel, snapshot, sourceDescriptionFooterAside, title, }: ReviewSurfaceProps): import("react").JSX.Element;
42
+ export declare function ReviewSurface({ commenting, externalUrl, gitIdentity, initialMode, interactive, onDeleteShare, onModeChange, providerLabel, repositoryUrl, settingsBar, signInLabel, snapshot, sourceDescriptionFooterAside, title, }: ReviewSurfaceProps): import("react").JSX.Element;
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from 'react';
2
+ export type ReviewModeItem<Mode extends string> = {
3
+ ariaLabel?: string;
4
+ icon: ReactNode;
5
+ indicator?: ReactNode;
6
+ label: string;
7
+ title?: string;
8
+ value: Mode;
9
+ };
10
+ export declare function ReviewTopBar<Mode extends string>({ actions, context, leading, mode, modes, onModeChange, onToggleSidebar, repository, repositoryTooltip, sidebarCollapsed, toggleTitle, }: {
11
+ actions?: ReactNode;
12
+ context?: ReactNode;
13
+ leading?: ReactNode;
14
+ mode: Mode;
15
+ modes: ReadonlyArray<ReviewModeItem<Mode>>;
16
+ onModeChange: (mode: Mode) => void;
17
+ onToggleSidebar: () => void;
18
+ repository: ReactNode;
19
+ repositoryTooltip?: string;
20
+ sidebarCollapsed: boolean;
21
+ toggleTitle: string;
22
+ }): import("react").JSX.Element;
@@ -2,7 +2,7 @@ import type { CodiffKeymap } from '../../config/types.ts';
2
2
  import type { DiffLineCount, PullRequestSource, SidebarMode, WalkthroughError } from '../../lib/app-types.ts';
3
3
  import type { ChangedFile, HistoryEntry, NarrativeWalkthrough, ReviewSource } from '../../types.ts';
4
4
  import type { NarrativeNavigation } from './walkthrough/useNarrativeNavigation.ts';
5
- export declare function Sidebar({ branchSource, commitFiles, commitViewOpen, currentSource, files, historyEntries, historyHasMore, historyLoading, keymap, mode, narrativeNavigation, narrativeWalkthrough, onActivatePath, onLoadMoreHistory, onModeChange, onSearchQueryChange, onSelectSource, onShareWalkthrough, onToggleCommitView, pullRequestSource, reloadDeltaPaths, searchQuery, selectedPath, shareWalkthroughDisabled, showWhitespace, viewed, walkthroughError, walkthroughLoading, walkthroughProgress, walkthroughUnread, }: {
5
+ export declare function Sidebar({ branchSource, commitFiles, commitViewOpen, currentSource, files, historyEntries, historyHasMore, historyLoading, keymap, mode, narrativeNavigation, narrativeWalkthrough, onActivatePath, onLoadMoreHistory, onSearchQueryChange, onSelectSource, onShareWalkthrough, onToggleCommitView, pullRequestSource, reloadDeltaPaths, searchQuery, selectedPath, shareWalkthroughDisabled, showWhitespace, viewed, walkthroughError, walkthroughLoading, walkthroughProgress, }: {
6
6
  branchSource: Extract<ReviewSource, {
7
7
  type: 'branch-diff';
8
8
  }> | null;
@@ -19,7 +19,6 @@ export declare function Sidebar({ branchSource, commitFiles, commitViewOpen, cur
19
19
  narrativeWalkthrough: NarrativeWalkthrough | null;
20
20
  onActivatePath: (path: string) => void;
21
21
  onLoadMoreHistory: () => void;
22
- onModeChange: (mode: SidebarMode) => void;
23
22
  onSearchQueryChange: (query: string) => void;
24
23
  onSelectSource: (source: ReviewSource) => void;
25
24
  onShareWalkthrough?: () => void;
@@ -38,7 +37,6 @@ export declare function Sidebar({ branchSource, commitFiles, commitViewOpen, cur
38
37
  responseLabelIndex: number;
39
38
  stageRevision: number;
40
39
  };
41
- walkthroughUnread: boolean;
42
40
  }): import("react").JSX.Element;
43
41
  export declare function DiffLineCountBadge({ ariaLabelPrefix, className, lineCount, }: {
44
42
  ariaLabelPrefix?: string;
package/dist/react.mjs CHANGED
@@ -7,11 +7,14 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { MarkdownEditor } from "@nkzw/mdx-editor";
8
8
  import { frontmatterPlugin, imagePlugin } from "@nkzw/mdx-editor/core";
9
9
  import { DownloadSimpleIcon } from "@phosphor-icons/react/DownloadSimple";
10
- import { Copy, ExternalLink, Trash2, X } from "lucide-react";
10
+ import { Copy, Trash2, X } from "lucide-react";
11
+ import { ArrowSquareOutIcon } from "@phosphor-icons/react/ArrowSquareOut";
12
+ import { ChatCircleIcon } from "@phosphor-icons/react/ChatCircle";
13
+ import { PathIcon } from "@phosphor-icons/react/Path";
14
+ import { TreeStructureIcon } from "@phosphor-icons/react/TreeStructure";
11
15
  import { FileTree, useFileTree } from "@pierre/trees/react";
12
16
  import { hydratePartialDiff, parseDiffFromFile, parsePatchFiles, registerCustomTheme, setCustomExtension } from "@pierre/diffs";
13
17
  import useRelativeTime from "@nkzw/use-relative-time";
14
- import { ChatCircleIcon } from "@phosphor-icons/react/ChatCircle";
15
18
  import { CaretDownIcon } from "@phosphor-icons/react/CaretDown";
16
19
  import "@phosphor-icons/react/CaretUp";
17
20
  import { CheckIcon } from "@phosphor-icons/react/Check";
@@ -26,13 +29,13 @@ import { SquareSplitVerticalIcon } from "@phosphor-icons/react/SquareSplitVertic
26
29
  import { CodeView, WorkerPoolContextProvider } from "@pierre/diffs/react";
27
30
  import { PersistentMarkdownEditor } from "@nkzw/mdx-editor/persistence";
28
31
  import { GitBranchIcon } from "@phosphor-icons/react/GitBranch";
29
- import { PathIcon } from "@phosphor-icons/react/Path";
30
32
  import { ShareNetworkIcon } from "@phosphor-icons/react/ShareNetwork";
31
33
  import { BugIcon } from "@phosphor-icons/react/Bug";
32
34
  import { FlaskIcon } from "@phosphor-icons/react/Flask";
33
35
  import { GearIcon } from "@phosphor-icons/react/Gear";
34
36
  import { ReadCvLogoIcon } from "@phosphor-icons/react/ReadCvLogo";
35
37
  import { WrenchIcon } from "@phosphor-icons/react/Wrench";
38
+ import { SidebarSimpleIcon } from "@phosphor-icons/react/SidebarSimple";
36
39
  import { ArrowLeftIcon } from "@phosphor-icons/react/ArrowLeft";
37
40
  import { ArrowRightIcon } from "@phosphor-icons/react/ArrowRight";
38
41
  import { CaretLeftIcon } from "@phosphor-icons/react/CaretLeft";
@@ -1067,7 +1070,7 @@ function PlanReviewSurface({ commenting, onDeleteShare, signInLabel = "Sign in t
1067
1070
  className: "plan-shell shared-plan-shell",
1068
1071
  "data-theme": snapshot.preferences.theme === "system" ? void 0 : snapshot.preferences.theme,
1069
1072
  children: [/* @__PURE__ */ jsx("header", {
1070
- className: "plan-header",
1073
+ className: "plan-header workspace-top-bar",
1071
1074
  children: /* @__PURE__ */ jsx("div", {
1072
1075
  className: "plan-title",
1073
1076
  title: snapshot.document.title,
@@ -6999,6 +7002,69 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
6999
7002
  });
7000
7003
  }
7001
7004
  //#endregion
7005
+ //#region app/components/ReviewTopBar.tsx
7006
+ function ReviewTopBar({ actions, context, leading, mode, modes, onModeChange, onToggleSidebar, repository, repositoryTooltip, sidebarCollapsed, toggleTitle }) {
7007
+ return /* @__PURE__ */ jsxs("header", {
7008
+ className: "review-top-bar workspace-top-bar",
7009
+ children: [
7010
+ /* @__PURE__ */ jsxs("div", {
7011
+ className: "review-top-bar-left",
7012
+ children: [
7013
+ leading,
7014
+ /* @__PURE__ */ jsx("button", {
7015
+ "aria-label": sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar",
7016
+ className: "sidebar-toggle-button",
7017
+ onClick: onToggleSidebar,
7018
+ title: toggleTitle,
7019
+ type: "button",
7020
+ children: /* @__PURE__ */ jsx(SidebarSimpleIcon, {
7021
+ "aria-hidden": true,
7022
+ size: 18,
7023
+ weight: "bold"
7024
+ })
7025
+ }),
7026
+ /* @__PURE__ */ jsx("div", {
7027
+ className: "review-top-bar-repository-slot",
7028
+ title: repositoryTooltip,
7029
+ children: repository
7030
+ })
7031
+ ]
7032
+ }),
7033
+ /* @__PURE__ */ jsx("div", {
7034
+ "aria-label": "Review mode",
7035
+ className: "review-mode-control",
7036
+ role: "tablist",
7037
+ children: modes.map((item) => /* @__PURE__ */ jsxs("button", {
7038
+ "aria-label": item.ariaLabel,
7039
+ "aria-selected": mode === item.value,
7040
+ onClick: () => onModeChange(item.value),
7041
+ role: "tab",
7042
+ title: item.title,
7043
+ type: "button",
7044
+ children: [
7045
+ item.icon,
7046
+ /* @__PURE__ */ jsx("span", {
7047
+ className: "review-mode-label",
7048
+ children: item.label
7049
+ }),
7050
+ item.indicator
7051
+ ]
7052
+ }, item.value))
7053
+ }),
7054
+ /* @__PURE__ */ jsxs("div", {
7055
+ className: "review-top-bar-right",
7056
+ children: [context ? /* @__PURE__ */ jsx("div", {
7057
+ className: "review-top-bar-context",
7058
+ children: context
7059
+ }) : null, actions ? /* @__PURE__ */ jsx("div", {
7060
+ className: "review-top-bar-actions",
7061
+ children: actions
7062
+ }) : null]
7063
+ })
7064
+ ]
7065
+ });
7066
+ }
7067
+ //#endregion
7002
7068
  //#region app/components/walkthrough/CommitView.tsx
7003
7069
  const TERMINAL_COLS = 80;
7004
7070
  const TERMINAL_ROWS = 12;
@@ -8686,7 +8752,7 @@ const disabledCommitMessage = async () => ({
8686
8752
  reason: "Shared walkthroughs are read-only.",
8687
8753
  status: "unavailable"
8688
8754
  });
8689
- function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMode, interactive, onDeleteShare, onModeChange, providerLabel = "provider", settingsBar, signInLabel = "Sign in to comment", snapshot, sourceDescriptionFooterAside, title }) {
8755
+ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMode, interactive, onDeleteShare, onModeChange, providerLabel = "provider", repositoryUrl, settingsBar, signInLabel = "Sign in to comment", snapshot, sourceDescriptionFooterAside, title }) {
8690
8756
  const canComment = commenting?.canComment ?? Boolean(interactive);
8691
8757
  const deleteShare = useCallback(async () => {
8692
8758
  if (!onDeleteShare || !window.confirm("Delete this shared walkthrough? This cannot be undone.")) return;
@@ -8709,10 +8775,22 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
8709
8775
  const keymap = useMemo(() => createDefaultConfig().keymap, []);
8710
8776
  const [fileSearchQuery, setFileSearchQuery] = useState("");
8711
8777
  const [uncontrolledSidebarMode, setUncontrolledSidebarMode] = useState(() => initialMode ?? (interactive ? "tree" : "walkthrough"));
8712
- const sidebarMode = Boolean(initialMode && onModeChange) ? initialMode : uncontrolledSidebarMode;
8778
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
8779
+ useEffect(() => {
8780
+ const handleKeyDown = (event) => {
8781
+ if (event.repeat || !matchesShortcut(event, keymap, "toggleSidebar")) return;
8782
+ event.preventDefault();
8783
+ setSidebarCollapsed((current) => !current);
8784
+ };
8785
+ window.addEventListener("keydown", handleKeyDown);
8786
+ return () => window.removeEventListener("keydown", handleKeyDown);
8787
+ }, [keymap]);
8788
+ const sidebarMode = Boolean(initialMode && onModeChange) && initialMode ? initialMode : uncontrolledSidebarMode;
8713
8789
  const [treeScrollTarget, setTreeScrollTarget] = useState(null);
8714
8790
  const { bumpItemVersion, collapsed, expandedGenerated, itemVersionByKey, selectedPath, setSelectedPath, toggleCollapsed, toggleViewed, viewed } = useReviewFileState({ initialSelectedPath: snapshot.files[0]?.path ?? null });
8715
8791
  const { resizeSidebar, sidebarWidth } = useResizableSidebar({
8792
+ collapseThreshold: 80,
8793
+ onCollapse: () => setSidebarCollapsed(true),
8716
8794
  onWidthCommit: writeSharedSidebarWidth,
8717
8795
  readWidth: readSharedSidebarWidth
8718
8796
  });
@@ -9102,8 +9180,10 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
9102
9180
  sourceDescriptionFooter
9103
9181
  });
9104
9182
  };
9105
- const sourceLabel = snapshot.repository.source.type === "working-tree" ? "" : ` · ${getSourceLabel(snapshot.repository.source)}`;
9106
- const rootLabel = `${compactPath(snapshot.repository.root)}${snapshot.branch ? ` (${snapshot.branch})` : ""}`;
9183
+ const sourceLabel = snapshot.repository.source.type === "working-tree" ? null : getSourceLabel(snapshot.repository.source);
9184
+ const rootLabel = repositoryUrl ? snapshot.repository.root : compactPath(snapshot.repository.root);
9185
+ const sourceExternalUrl = snapshot.repository.source.type === "pull-request" ? externalUrl ?? snapshot.repository.source.url : null;
9186
+ const repositoryLinkUrl = repositoryUrl ?? sourceExternalUrl;
9107
9187
  const walkthroughStatus = walkthroughRequestPending && interactive?.walkthroughStatus !== "ready" ? "generating" : interactive?.walkthroughStatus;
9108
9188
  const [walkthroughProgressRevision, setWalkthroughProgressRevision] = useState(0);
9109
9189
  const previousWalkthroughStatusRef = useRef(walkthroughStatus);
@@ -9119,57 +9199,120 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
9119
9199
  const requestWalkthrough = () => {
9120
9200
  startWalkthroughGeneration();
9121
9201
  };
9202
+ const reviewModes = [
9203
+ {
9204
+ icon: /* @__PURE__ */ jsx(PathIcon, {
9205
+ "aria-hidden": true,
9206
+ size: 14,
9207
+ weight: "bold"
9208
+ }),
9209
+ label: "Walkthrough",
9210
+ value: "walkthrough"
9211
+ },
9212
+ {
9213
+ icon: /* @__PURE__ */ jsx(TreeStructureIcon, {
9214
+ "aria-hidden": true,
9215
+ size: 14,
9216
+ weight: "bold"
9217
+ }),
9218
+ label: "Tree",
9219
+ value: "tree"
9220
+ },
9221
+ ...showCommentsTab ? [{
9222
+ ariaLabel: generalCommentCount > 0 ? `Comments (${generalCommentCount})` : "Comments",
9223
+ icon: /* @__PURE__ */ jsx(ChatCircleIcon, {
9224
+ "aria-hidden": true,
9225
+ size: 14,
9226
+ weight: "bold"
9227
+ }),
9228
+ indicator: generalCommentCount > 0 ? /* @__PURE__ */ jsx("span", {
9229
+ "aria-hidden": true,
9230
+ className: "review-mode-count",
9231
+ children: generalCommentCount
9232
+ }) : void 0,
9233
+ label: "Comments",
9234
+ title: generalCommentCount > 0 ? `${generalCommentCount} ${generalCommentCount === 1 ? "comment" : "comments"}` : "Comments",
9235
+ value: "comments"
9236
+ }] : []
9237
+ ];
9238
+ const topBarActions = onDeleteShare || settingsBar ? /* @__PURE__ */ jsxs(Fragment$1, { children: [onDeleteShare ? /* @__PURE__ */ jsx(Button, {
9239
+ action: deleteShare,
9240
+ "aria-label": "Delete shared walkthrough",
9241
+ pendingPlaceholder: "…",
9242
+ size: "icon",
9243
+ title: "Delete shared walkthrough",
9244
+ type: "button",
9245
+ variant: "destructive",
9246
+ children: /* @__PURE__ */ jsx(Trash2, {
9247
+ "aria-hidden": true,
9248
+ size: 16
9249
+ })
9250
+ }) : null, settingsBar ? /* @__PURE__ */ jsx("div", {
9251
+ className: "review-top-bar-settings",
9252
+ children: settingsBar
9253
+ }) : null] }) : void 0;
9122
9254
  return /* @__PURE__ */ jsxs("div", {
9123
- className: `app-shell share-shell${interactive ? " merge-request-shell" : ""}`,
9255
+ className: `app-shell share-shell${interactive ? " merge-request-shell" : ""}${sidebarCollapsed ? " sidebar-collapsed" : ""}`,
9124
9256
  "data-theme": shellTheme,
9125
- style: { gridTemplateColumns: `${sidebarWidth}px 0 minmax(0, 1fr)` },
9257
+ style: sidebarCollapsed ? void 0 : { gridTemplateColumns: `${sidebarWidth}px 0 minmax(0, 1fr)` },
9126
9258
  children: [
9259
+ /* @__PURE__ */ jsx(ReviewTopBar, {
9260
+ actions: topBarActions,
9261
+ context: /* @__PURE__ */ jsxs(Fragment$1, { children: [snapshot.branch ? /* @__PURE__ */ jsx("span", {
9262
+ className: "review-top-bar-branch",
9263
+ title: snapshot.branch,
9264
+ children: snapshot.branch
9265
+ }) : null, sourceLabel ? sourceExternalUrl ? /* @__PURE__ */ jsxs("a", {
9266
+ "aria-label": `Open ${sourceLabel} in ${providerLabel}`,
9267
+ className: "review-top-bar-source",
9268
+ href: sourceExternalUrl,
9269
+ rel: "noreferrer",
9270
+ target: "_blank",
9271
+ title: `Open ${sourceLabel} in ${providerLabel}`,
9272
+ children: [/* @__PURE__ */ jsx("span", { children: sourceLabel }), /* @__PURE__ */ jsx(ArrowSquareOutIcon, {
9273
+ "aria-hidden": true,
9274
+ size: 14,
9275
+ weight: "bold"
9276
+ })]
9277
+ }) : /* @__PURE__ */ jsx("span", {
9278
+ className: "review-top-bar-source",
9279
+ children: sourceLabel
9280
+ }) : null] }),
9281
+ leading: interactive ? /* @__PURE__ */ jsx("button", {
9282
+ "aria-label": "Back to Codiff",
9283
+ className: "merge-request-nav-button merge-request-home-button",
9284
+ onClick: interactive.onHome,
9285
+ title: "Back to Codiff",
9286
+ type: "button",
9287
+ children: /* @__PURE__ */ jsx("img", {
9288
+ alt: "",
9289
+ "aria-hidden": true,
9290
+ className: "merge-request-nav-icon",
9291
+ draggable: false,
9292
+ src: "/icon.png"
9293
+ })
9294
+ }) : void 0,
9295
+ mode: sidebarMode,
9296
+ modes: reviewModes,
9297
+ onModeChange: changeSidebarMode,
9298
+ onToggleSidebar: () => setSidebarCollapsed((current) => !current),
9299
+ repository: repositoryLinkUrl ? /* @__PURE__ */ jsx("a", {
9300
+ className: "review-top-bar-repository",
9301
+ href: repositoryLinkUrl,
9302
+ rel: "noreferrer",
9303
+ target: repositoryUrl ? void 0 : "_blank",
9304
+ children: rootLabel
9305
+ }) : /* @__PURE__ */ jsx("span", {
9306
+ className: "review-top-bar-repository",
9307
+ children: rootLabel
9308
+ }),
9309
+ repositoryTooltip: snapshot.repository.root,
9310
+ sidebarCollapsed,
9311
+ toggleTitle: `${sidebarCollapsed ? "Expand" : "Collapse"} sidebar`
9312
+ }),
9127
9313
  /* @__PURE__ */ jsxs("aside", {
9128
9314
  className: "squircle sidebar",
9129
9315
  children: [
9130
- /* @__PURE__ */ jsx("div", {
9131
- className: "sidebar-header",
9132
- children: /* @__PURE__ */ jsxs("div", {
9133
- className: "sidebar-path-row",
9134
- children: [
9135
- interactive ? /* @__PURE__ */ jsx("button", {
9136
- "aria-label": "Back to Codiff",
9137
- className: "merge-request-nav-button merge-request-home-button",
9138
- onClick: interactive.onHome,
9139
- title: "Back to Codiff",
9140
- type: "button",
9141
- children: /* @__PURE__ */ jsx("img", {
9142
- alt: "",
9143
- "aria-hidden": true,
9144
- className: "merge-request-nav-icon",
9145
- draggable: false,
9146
- src: "/icon.png"
9147
- })
9148
- }) : null,
9149
- /* @__PURE__ */ jsxs("div", {
9150
- className: "sidebar-path",
9151
- title: title ?? snapshot.repository.root,
9152
- children: [
9153
- title ? `${title} · ` : null,
9154
- rootLabel,
9155
- sourceLabel
9156
- ]
9157
- }),
9158
- externalUrl ? /* @__PURE__ */ jsx("a", {
9159
- "aria-label": `Open merge request in ${providerLabel}`,
9160
- className: "merge-request-nav-button",
9161
- href: externalUrl,
9162
- rel: "noreferrer",
9163
- target: "_blank",
9164
- title: `Open merge request in ${providerLabel}`,
9165
- children: /* @__PURE__ */ jsx(ExternalLink, {
9166
- "aria-hidden": true,
9167
- size: 16
9168
- })
9169
- }) : null
9170
- ]
9171
- })
9172
- }),
9173
9316
  /* @__PURE__ */ jsx("div", {
9174
9317
  className: "sidebar-search-row",
9175
9318
  children: /* @__PURE__ */ jsx("input", {
@@ -9182,40 +9325,6 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
9182
9325
  value: fileSearchQuery
9183
9326
  })
9184
9327
  }),
9185
- /* @__PURE__ */ jsxs("div", {
9186
- "aria-label": "Review order",
9187
- className: `sidebar-mode-toggle${showCommentsTab ? " sidebar-mode-toggle-with-comments" : ""}`,
9188
- role: "tablist",
9189
- children: [
9190
- /* @__PURE__ */ jsx("button", {
9191
- "aria-selected": sidebarMode === "tree",
9192
- onClick: () => changeSidebarMode("tree"),
9193
- role: "tab",
9194
- type: "button",
9195
- children: "Tree"
9196
- }),
9197
- /* @__PURE__ */ jsx("button", {
9198
- "aria-selected": sidebarMode === "walkthrough",
9199
- onClick: () => changeSidebarMode("walkthrough"),
9200
- role: "tab",
9201
- type: "button",
9202
- children: "Walkthrough"
9203
- }),
9204
- showCommentsTab ? /* @__PURE__ */ jsxs("button", {
9205
- "aria-label": generalCommentCount > 0 ? `Comments (${generalCommentCount})` : "Comments",
9206
- "aria-selected": sidebarMode === "comments",
9207
- onClick: () => changeSidebarMode("comments"),
9208
- role: "tab",
9209
- title: generalCommentCount > 0 ? `${generalCommentCount} ${generalCommentCount === 1 ? "comment" : "comments"}` : "Comments",
9210
- type: "button",
9211
- children: [/* @__PURE__ */ jsx("span", { children: "Comments" }), generalCommentCount > 0 ? /* @__PURE__ */ jsx("span", {
9212
- "aria-hidden": true,
9213
- className: "sidebar-tab-count",
9214
- children: generalCommentCount
9215
- }) : null]
9216
- }) : null
9217
- ]
9218
- }),
9219
9328
  sidebarMode === "tree" ? /* @__PURE__ */ jsx(ReviewFileTree, {
9220
9329
  files: visibleFiles,
9221
9330
  onActivatePath: activateTreePath,
@@ -9243,29 +9352,13 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
9243
9352
  }), walkthroughStatusDescription ? /* @__PURE__ */ jsx("span", { children: walkthroughStatusDescription }) : null]
9244
9353
  })
9245
9354
  }),
9246
- onDeleteShare || settingsBar || showTotalLineCount ? /* @__PURE__ */ jsxs("div", {
9355
+ showTotalLineCount ? /* @__PURE__ */ jsx("div", {
9247
9356
  className: "sidebar-settings-bar",
9248
- children: [
9249
- onDeleteShare ? /* @__PURE__ */ jsx(Button, {
9250
- action: deleteShare,
9251
- "aria-label": "Delete shared walkthrough",
9252
- pendingPlaceholder: "…",
9253
- size: "icon",
9254
- title: "Delete shared walkthrough",
9255
- type: "button",
9256
- variant: "destructive",
9257
- children: /* @__PURE__ */ jsx(Trash2, {
9258
- "aria-hidden": true,
9259
- size: 16
9260
- })
9261
- }) : null,
9262
- settingsBar,
9263
- showTotalLineCount ? /* @__PURE__ */ jsx(DiffLineCountBadge, {
9264
- ariaLabelPrefix: "Total change",
9265
- className: "sidebar-total-line-count sidebar-settings-line-count",
9266
- lineCount: totalLineCount
9267
- }) : null
9268
- ]
9357
+ children: /* @__PURE__ */ jsx(DiffLineCountBadge, {
9358
+ ariaLabelPrefix: "Total change",
9359
+ className: "sidebar-total-line-count sidebar-settings-line-count",
9360
+ lineCount: totalLineCount
9361
+ })
9269
9362
  }) : null
9270
9363
  ]
9271
9364
  }),
package/dist/style.css CHANGED
@@ -4805,6 +4805,7 @@ form._multiFieldForm_sre1d_1628 {
4805
4805
  }
4806
4806
 
4807
4807
  .app-shell {
4808
+ grid-template-rows: 40px minmax(0, 1fr);
4808
4809
  grid-template-columns: 292px 0 minmax(0, 1fr);
4809
4810
  height: 100%;
4810
4811
  display: grid;
@@ -4818,18 +4819,21 @@ form._multiFieldForm_sre1d_1628 {
4818
4819
  overflow: hidden;
4819
4820
  }
4820
4821
 
4821
- .plan-header {
4822
+ .workspace-top-bar {
4822
4823
  -webkit-app-region: drag;
4823
4824
  backdrop-filter: blur(28px) saturate(1.3);
4824
4825
  background: var(--sidebar-bg);
4825
4826
  border-bottom: 1px solid var(--sidebar-border);
4826
4827
  align-items: center;
4827
4828
  height: 40px;
4828
- padding: 0 14px 0 78px;
4829
4829
  display: flex;
4830
4830
  }
4831
4831
 
4832
- html[data-codiff-platform="darwin"] .plan-header {
4832
+ .plan-header {
4833
+ padding: 0 14px 0 78px;
4834
+ }
4835
+
4836
+ html[data-codiff-platform="darwin"] .workspace-top-bar {
4833
4837
  backdrop-filter: none;
4834
4838
  background: var(--sidebar-vibrancy-tint);
4835
4839
  }
@@ -5238,7 +5242,6 @@ html[data-codiff-platform="darwin"] .plan-header {
5238
5242
  }
5239
5243
 
5240
5244
  .app-shell.sidebar-collapsed {
5241
- grid-template-rows: auto minmax(0, 1fr);
5242
5245
  grid-template-columns: minmax(0, 1fr);
5243
5246
  }
5244
5247
 
@@ -5246,45 +5249,190 @@ html[data-codiff-platform="darwin"] .plan-header {
5246
5249
  display: none;
5247
5250
  }
5248
5251
 
5249
- .collapsed-sidebar-bar {
5250
- -webkit-app-region: drag;
5251
- backdrop-filter: blur(28px) saturate(1.3);
5252
- background: var(--sidebar-bg);
5253
- border-bottom: 1px solid var(--sidebar-border);
5254
- box-sizing: border-box;
5255
- corner-shape: initial;
5256
- border-radius: 0;
5257
- grid-column: 1 / -1;
5252
+ .review-top-bar {
5253
+ grid-area: 1 / 1 / auto / -1;
5254
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
5255
+ gap: 12px;
5256
+ min-width: 0;
5257
+ padding: 0 14px 0 78px;
5258
+ display: grid;
5259
+ }
5260
+
5261
+ .share-shell .review-top-bar, .app-shell.window-fullscreen .review-top-bar {
5262
+ padding-left: 14px;
5263
+ }
5264
+
5265
+ .review-top-bar-left, .review-top-bar-right {
5258
5266
  align-items: center;
5259
5267
  gap: 8px;
5260
- height: 40px;
5261
- margin: 0;
5262
- padding: 0 14px 0 78px;
5268
+ min-width: 0;
5263
5269
  display: flex;
5264
5270
  }
5265
5271
 
5266
- html[data-codiff-platform="darwin"] .collapsed-sidebar-bar {
5267
- backdrop-filter: none;
5268
- background: var(--sidebar-vibrancy-tint);
5272
+ .review-top-bar-left {
5273
+ justify-content: flex-start;
5269
5274
  }
5270
5275
 
5271
- .app-shell.window-fullscreen .collapsed-sidebar-bar {
5272
- padding-left: 14px;
5276
+ .review-top-bar-right {
5277
+ justify-content: flex-end;
5273
5278
  }
5274
5279
 
5275
- .collapsed-sidebar-label {
5280
+ .review-top-bar-repository-slot {
5276
5281
  color: var(--sidebar-text);
5277
5282
  font-family: var(--font-mono);
5278
- text-overflow: ellipsis;
5279
- white-space: nowrap;
5280
5283
  flex: 1;
5284
+ align-items: center;
5281
5285
  min-width: 0;
5282
5286
  font-size: 12px;
5283
5287
  font-weight: 600;
5284
5288
  line-height: 1.35;
5289
+ display: flex;
5290
+ }
5291
+
5292
+ .review-top-bar-repository {
5293
+ -webkit-app-region: no-drag;
5294
+ text-overflow: ellipsis;
5295
+ white-space: nowrap;
5296
+ flex: 1;
5297
+ min-width: 0;
5298
+ overflow: hidden;
5299
+ }
5300
+
5301
+ .review-top-bar-branch {
5302
+ color: var(--muted);
5303
+ corner-shape: squircle;
5304
+ font: 600 12px/1 var(--font-sans);
5305
+ text-overflow: ellipsis;
5306
+ white-space: nowrap;
5307
+ border-radius: 14px;
5308
+ flex: none;
5309
+ align-items: center;
5310
+ max-width: min(240px, 24vw);
5311
+ padding: 4px 8px;
5312
+ display: inline-flex;
5313
+ overflow: hidden;
5314
+ }
5315
+
5316
+ a.review-top-bar-repository, a.review-top-bar-source {
5317
+ color: inherit;
5318
+ text-decoration: none;
5319
+ }
5320
+
5321
+ a.review-top-bar-repository:hover, a.review-top-bar-source:hover {
5322
+ color: var(--text);
5323
+ }
5324
+
5325
+ a.review-top-bar-repository:focus-visible, a.review-top-bar-source:focus-visible {
5326
+ outline: 1px solid var(--tree-selection-focus);
5327
+ outline-offset: 2px;
5328
+ border-radius: 3px;
5329
+ }
5330
+
5331
+ .review-top-bar-source {
5332
+ -webkit-app-region: no-drag;
5333
+ color: var(--sidebar-text);
5334
+ font: 600 12px/1.35 var(--font-mono);
5335
+ white-space: nowrap;
5336
+ flex: none;
5337
+ align-items: center;
5338
+ gap: 4px;
5339
+ display: inline-flex;
5340
+ }
5341
+
5342
+ .review-top-bar-context {
5343
+ align-items: center;
5344
+ gap: 8px;
5345
+ min-width: 0;
5346
+ display: flex;
5347
+ }
5348
+
5349
+ .review-top-bar-actions {
5350
+ -webkit-app-region: no-drag;
5351
+ flex: none;
5352
+ align-items: center;
5353
+ gap: 6px;
5354
+ min-width: 0;
5355
+ display: flex;
5356
+ }
5357
+
5358
+ .review-top-bar-settings, .review-top-bar-settings > * {
5359
+ flex: none;
5360
+ align-items: center;
5361
+ width: auto;
5362
+ display: flex;
5363
+ }
5364
+
5365
+ .review-mode-control {
5366
+ -webkit-app-region: no-drag;
5367
+ corner-shape: squircle;
5368
+ border-radius: 16px;
5369
+ flex: none;
5370
+ align-items: center;
5371
+ gap: 2px;
5372
+ height: 30px;
5373
+ padding: 2px;
5374
+ display: inline-flex;
5375
+ }
5376
+
5377
+ .review-top-bar-branch, .review-mode-control {
5378
+ background: #7f7f7f14;
5379
+ border: 1px solid #7f7f7f1f;
5380
+ }
5381
+
5382
+ .review-mode-control button {
5383
+ color: var(--muted);
5384
+ corner-shape: squircle;
5385
+ cursor: pointer;
5386
+ font: 600 11px/1 var(--font-sans);
5387
+ white-space: nowrap;
5388
+ background: none;
5389
+ border: 0;
5390
+ border-radius: 14px;
5391
+ justify-content: center;
5392
+ align-items: center;
5393
+ gap: 5px;
5394
+ min-width: 0;
5395
+ height: 24px;
5396
+ padding: 0 8px;
5397
+ display: inline-flex;
5398
+ }
5399
+
5400
+ .review-mode-control button:hover {
5401
+ color: var(--sidebar-text);
5402
+ background: #7f7f7f17;
5403
+ }
5404
+
5405
+ .review-mode-control button[aria-selected="true"] {
5406
+ background: var(--hover-wash);
5407
+ color: var(--sidebar-text);
5408
+ box-shadow: 0 1px 2px #00000014;
5409
+ }
5410
+
5411
+ .review-mode-label {
5412
+ text-overflow: ellipsis;
5413
+ min-width: 0;
5285
5414
  overflow: hidden;
5286
5415
  }
5287
5416
 
5417
+ .review-mode-count {
5418
+ color: inherit;
5419
+ font: 700 10px/1 var(--font-mono);
5420
+ text-align: center;
5421
+ background: #7f7f7f29;
5422
+ border-radius: 999px;
5423
+ flex: none;
5424
+ min-width: 16px;
5425
+ padding: 3px 5px;
5426
+ }
5427
+
5428
+ .review-mode-dot {
5429
+ background: var(--sidebar-ref);
5430
+ border-radius: 50%;
5431
+ flex: none;
5432
+ width: 6px;
5433
+ height: 6px;
5434
+ }
5435
+
5288
5436
  .sidebar-toggle-button {
5289
5437
  -webkit-app-region: no-drag;
5290
5438
  color: var(--muted);
@@ -5321,6 +5469,10 @@ html[data-codiff-platform="darwin"] .collapsed-sidebar-bar {
5321
5469
  position: relative;
5322
5470
  }
5323
5471
 
5472
+ .app-shell > .sidebar, .app-shell > .sidebar-resizer, .app-shell > .review {
5473
+ grid-row: 2;
5474
+ }
5475
+
5324
5476
  .sidebar-resizer:before {
5325
5477
  content: "";
5326
5478
  background: none;
@@ -5581,31 +5733,6 @@ html[data-codiff-platform="darwin"] .sidebar {
5581
5733
  background: var(--sidebar-vibrancy-tint);
5582
5734
  }
5583
5735
 
5584
- .sidebar-header {
5585
- -webkit-app-region: drag;
5586
- border-bottom: 1px solid var(--sidebar-border);
5587
- flex: none;
5588
- min-width: 0;
5589
- padding: 0 14px;
5590
- }
5591
-
5592
- .sidebar-path-row {
5593
- align-items: center;
5594
- gap: 8px;
5595
- min-width: 0;
5596
- min-height: 38px;
5597
- padding-left: 64px;
5598
- display: flex;
5599
- }
5600
-
5601
- .app-shell.window-fullscreen .sidebar-path-row, .share-shell .sidebar-path-row {
5602
- padding-left: 0;
5603
- }
5604
-
5605
- .merge-request-shell .sidebar-path-row {
5606
- gap: 6px;
5607
- }
5608
-
5609
5736
  .merge-request-nav-button {
5610
5737
  color: var(--muted);
5611
5738
  cursor: pointer;
@@ -5640,19 +5767,6 @@ html[data-codiff-platform="darwin"] .sidebar {
5640
5767
  padding: 18px 14px;
5641
5768
  }
5642
5769
 
5643
- .sidebar-path {
5644
- color: var(--sidebar-text);
5645
- font-family: var(--font-mono);
5646
- text-overflow: ellipsis;
5647
- white-space: nowrap;
5648
- flex: 1;
5649
- min-width: 0;
5650
- font-size: 12px;
5651
- font-weight: 600;
5652
- line-height: 1.35;
5653
- overflow: hidden;
5654
- }
5655
-
5656
5770
  .sidebar-search-row {
5657
5771
  flex: none;
5658
5772
  gap: 8px;
@@ -5660,78 +5774,6 @@ html[data-codiff-platform="darwin"] .sidebar {
5660
5774
  display: grid;
5661
5775
  }
5662
5776
 
5663
- .sidebar-mode-toggle {
5664
- border-bottom: 1px solid var(--sidebar-border);
5665
- flex: none;
5666
- grid-template-columns: minmax(48px, .75fr) minmax(96px, 1.35fr) minmax(68px, .9fr);
5667
- gap: 6px;
5668
- padding: 0 8px;
5669
- display: grid;
5670
- }
5671
-
5672
- .share-shell .sidebar-mode-toggle {
5673
- grid-template-columns: repeat(2, minmax(0, 1fr));
5674
- }
5675
-
5676
- .share-shell .sidebar-mode-toggle-with-comments, .merge-request-shell .sidebar-mode-toggle {
5677
- grid-template-columns: minmax(42px, .65fr) minmax(88px, 1.05fr) minmax(102px, 1.3fr);
5678
- }
5679
-
5680
- .sidebar-mode-toggle button {
5681
- -webkit-app-region: no-drag;
5682
- color: var(--muted);
5683
- corner-shape: squircle;
5684
- cursor: pointer;
5685
- font: 600 12px/1.35 var(--font-sans);
5686
- background: none;
5687
- border: 0;
5688
- border-radius: 24px 24px 0 0;
5689
- justify-content: center;
5690
- align-items: center;
5691
- gap: 5px;
5692
- min-width: 0;
5693
- height: 30px;
5694
- padding: 0 8px;
5695
- display: inline-flex;
5696
- }
5697
-
5698
- .sidebar-mode-toggle button span:first-child {
5699
- text-overflow: ellipsis;
5700
- min-width: 0;
5701
- overflow: hidden;
5702
- }
5703
-
5704
- .sidebar-tab-count {
5705
- color: var(--muted);
5706
- font: 700 10px/1 var(--font-mono);
5707
- text-align: center;
5708
- background: #7f7f7f29;
5709
- border-radius: 999px;
5710
- flex: none;
5711
- min-width: 16px;
5712
- padding: 3px 5px;
5713
- }
5714
-
5715
- .sidebar-mode-toggle button[aria-selected="true"] .sidebar-tab-count {
5716
- color: var(--sidebar-text);
5717
- background: #7f7f7f38;
5718
- }
5719
-
5720
- .sidebar-mode-toggle button:hover:not(:disabled) {
5721
- color: var(--sidebar-text);
5722
- background: #7f7f7f1a;
5723
- }
5724
-
5725
- .sidebar-mode-toggle button[aria-selected="true"] {
5726
- color: var(--sidebar-text);
5727
- background: #7f7f7f24;
5728
- }
5729
-
5730
- .sidebar-mode-toggle button:disabled {
5731
- cursor: default;
5732
- opacity: .45;
5733
- }
5734
-
5735
5777
  .sidebar-settings-bar {
5736
5778
  border-top: 1px solid var(--sidebar-border);
5737
5779
  flex: none;
@@ -8425,25 +8467,18 @@ diffs-container .review-comment-thread {
8425
8467
  padding: 3px 6px;
8426
8468
  }
8427
8469
 
8428
- @container sidebar (width <= 260px) {
8429
- .sidebar-mode-toggle {
8430
- grid-template-columns: minmax(42px, .75fr) minmax(82px, 1.35fr) minmax(58px, .9fr);
8431
- gap: 4px;
8432
- padding-inline: 8px;
8470
+ @media (width <= 720px) {
8471
+ .review-top-bar-repository-slot, .review-top-bar-context {
8472
+ display: none;
8433
8473
  }
8474
+ }
8434
8475
 
8435
- .share-shell .sidebar-mode-toggle-with-comments, .merge-request-shell .sidebar-mode-toggle {
8436
- grid-template-columns: minmax(40px, .65fr) minmax(78px, 1.05fr) minmax(88px, 1.3fr);
8476
+ @media (width <= 480px) {
8477
+ .review-mode-control button {
8478
+ padding-inline: 7px;
8437
8479
  }
8438
8480
 
8439
- .sidebar-mode-toggle button {
8440
- gap: 4px;
8441
- padding-inline: 4px;
8442
- font-size: 11px;
8443
- }
8444
-
8445
- .sidebar-tab-count {
8446
- min-width: 14px;
8447
- padding-inline: 4px;
8481
+ .review-mode-label {
8482
+ display: none;
8448
8483
  }
8449
8484
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nkzw/codiff-core",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "A fast diff viewer.",
5
5
  "license": "MIT",
6
6
  "author": {