@tooee/view 0.1.22 → 0.2.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.
Files changed (83) hide show
  1. package/README.md +67 -12
  2. package/dist/View.d.ts.map +1 -1
  3. package/dist/View.js +5 -1
  4. package/dist/View.js.map +1 -1
  5. package/dist/components/ViewScreen.d.ts +28 -0
  6. package/dist/components/ViewScreen.d.ts.map +1 -0
  7. package/dist/components/ViewScreen.js +29 -0
  8. package/dist/components/ViewScreen.js.map +1 -0
  9. package/dist/components/subviews/CodeSubview.d.ts +1 -1
  10. package/dist/components/subviews/CodeSubview.d.ts.map +1 -1
  11. package/dist/components/subviews/CodeSubview.js +20 -89
  12. package/dist/components/subviews/CodeSubview.js.map +1 -1
  13. package/dist/components/subviews/CustomSubview.d.ts +1 -1
  14. package/dist/components/subviews/CustomSubview.d.ts.map +1 -1
  15. package/dist/components/subviews/CustomSubview.js +19 -94
  16. package/dist/components/subviews/CustomSubview.js.map +1 -1
  17. package/dist/components/subviews/MarkdownSubview.d.ts +1 -1
  18. package/dist/components/subviews/MarkdownSubview.d.ts.map +1 -1
  19. package/dist/components/subviews/MarkdownSubview.js +32 -106
  20. package/dist/components/subviews/MarkdownSubview.js.map +1 -1
  21. package/dist/components/subviews/TableSubview.d.ts +1 -1
  22. package/dist/components/subviews/TableSubview.d.ts.map +1 -1
  23. package/dist/components/subviews/TableSubview.js +22 -123
  24. package/dist/components/subviews/TableSubview.js.map +1 -1
  25. package/dist/components/subviews/index.d.ts +0 -1
  26. package/dist/components/subviews/index.d.ts.map +1 -1
  27. package/dist/components/subviews/index.js +0 -1
  28. package/dist/components/subviews/index.js.map +1 -1
  29. package/dist/components/subviews/types.d.ts +6 -0
  30. package/dist/components/subviews/types.d.ts.map +1 -1
  31. package/dist/default-provider.d.ts +6 -3
  32. package/dist/default-provider.d.ts.map +1 -1
  33. package/dist/default-provider.js +24 -34
  34. package/dist/default-provider.js.map +1 -1
  35. package/dist/hooks/index.d.ts +2 -3
  36. package/dist/hooks/index.d.ts.map +1 -1
  37. package/dist/hooks/index.js +2 -3
  38. package/dist/hooks/index.js.map +1 -1
  39. package/dist/hooks/useContentCommands.d.ts +15 -0
  40. package/dist/hooks/useContentCommands.d.ts.map +1 -0
  41. package/dist/hooks/useContentCommands.js +21 -0
  42. package/dist/hooks/useContentCommands.js.map +1 -0
  43. package/dist/hooks/useViewCommandContext.d.ts +10 -42
  44. package/dist/hooks/useViewCommandContext.d.ts.map +1 -1
  45. package/dist/hooks/useViewCommandContext.js +3 -30
  46. package/dist/hooks/useViewCommandContext.js.map +1 -1
  47. package/dist/index.d.ts +2 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +1 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/types.d.ts +15 -16
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/types.js.map +1 -1
  54. package/package.json +14 -14
  55. package/src/View.tsx +6 -1
  56. package/src/components/ViewScreen.tsx +76 -0
  57. package/src/components/subviews/CodeSubview.tsx +30 -120
  58. package/src/components/subviews/CustomSubview.tsx +32 -123
  59. package/src/components/subviews/MarkdownSubview.tsx +49 -130
  60. package/src/components/subviews/TableSubview.tsx +36 -164
  61. package/src/components/subviews/index.ts +0 -1
  62. package/src/components/subviews/types.ts +6 -0
  63. package/src/default-provider.ts +37 -34
  64. package/src/hooks/index.ts +2 -7
  65. package/src/hooks/useContentCommands.ts +29 -0
  66. package/src/hooks/useViewCommandContext.ts +13 -81
  67. package/src/index.ts +1 -1
  68. package/src/types.ts +15 -16
  69. package/dist/components/SubviewLayout.d.ts +0 -16
  70. package/dist/components/SubviewLayout.d.ts.map +0 -1
  71. package/dist/components/SubviewLayout.js +0 -18
  72. package/dist/components/SubviewLayout.js.map +0 -1
  73. package/dist/hooks/useMarkState.d.ts +0 -14
  74. package/dist/hooks/useMarkState.d.ts.map +0 -1
  75. package/dist/hooks/useMarkState.js +0 -71
  76. package/dist/hooks/useMarkState.js.map +0 -1
  77. package/dist/hooks/useViewCommands.d.ts +0 -13
  78. package/dist/hooks/useViewCommands.d.ts.map +0 -1
  79. package/dist/hooks/useViewCommands.js +0 -20
  80. package/dist/hooks/useViewCommands.js.map +0 -1
  81. package/src/components/SubviewLayout.tsx +0 -48
  82. package/src/hooks/useMarkState.ts +0 -100
  83. package/src/hooks/useViewCommands.ts +0 -36
@@ -0,0 +1,21 @@
1
+ import { useState } from "react";
2
+ import { useCopyCommand, useToggleLineNumbersCommand } from "@tooee/shell";
3
+ import { useConfig } from "@tooee/config";
4
+ /**
5
+ * The commands a content viewer owns on top of `DocumentScreen`: copying the
6
+ * whole document and toggling the line-number gutter. Theme, quit, actions and
7
+ * every row-level command belong to the document controller and its screen.
8
+ */
9
+ export function useContentCommands({ content, textContent }) {
10
+ const config = useConfig();
11
+ const [showLineNumbers, setShowLineNumbers] = useState(config.view?.gutter ?? true);
12
+ useCopyCommand({
13
+ getText: () => (content ? textContent : undefined),
14
+ });
15
+ useToggleLineNumbersCommand({
16
+ showLineNumbers,
17
+ onToggle: () => setShowLineNumbers((v) => !v),
18
+ });
19
+ return { showLineNumbers };
20
+ }
21
+ //# sourceMappingURL=useContentCommands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useContentCommands.js","sourceRoot":"","sources":["../../src/hooks/useContentCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAQzC;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAE,OAAO,EAAE,WAAW,EAA4B;IACnF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAA;IAEnF,cAAc,CAAC;QACb,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;KACnD,CAAC,CAAA;IACF,2BAA2B,CAAC;QAC1B,eAAe;QACf,QAAQ,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;KAC9C,CAAC,CAAA;IAEF,OAAO,EAAE,eAAe,EAAE,CAAA;AAC5B,CAAC"}
@@ -1,20 +1,18 @@
1
- import type { Mode } from "@tooee/commands";
2
- import type { NavigationState } from "@tooee/shell";
3
1
  import type { MarkSet } from "@tooee/marks";
4
2
  import type { AnyContent } from "../types.js";
5
- /** The `view` field contributed to the command context (see augmentation below). */
3
+ /**
4
+ * The `view` field contributed to the command context (see augmentation below).
5
+ *
6
+ * This slice is content-only. Row state — cursor, selection, active and
7
+ * selected rows — is generic to every row document and lives on `ctx.document`,
8
+ * which `DocumentScreen` provides alongside this.
9
+ */
6
10
  export interface ViewCommandContext {
7
11
  content: AnyContent;
8
12
  format: string;
9
13
  title?: string;
10
14
  data?: unknown;
11
- cursor: number | null;
12
- selection: {
13
- start: number;
14
- end: number;
15
- } | null;
16
- mode: Mode;
17
- toggledIndices: Set<number>;
15
+ /** Reload the content from its provider. */
18
16
  reload: () => void;
19
17
  marks: {
20
18
  setMarkSet: (set: MarkSet) => void;
@@ -23,15 +21,12 @@ export interface ViewCommandContext {
23
21
  userMarks: MarkSet[];
24
22
  providerMarks: MarkSet[];
25
23
  };
26
- /** Subview extras (e.g. activeRow/selectedRows for tables). */
27
- [key: string]: unknown;
28
24
  }
29
25
  declare module "@tooee/commands" {
30
26
  interface CommandContext {
31
27
  view: ViewCommandContext;
32
28
  }
33
29
  }
34
- type ViewNavigationContext = Pick<NavigationState, "cursor" | "selection" | "toggledIndices">;
35
30
  export interface CreateViewCommandContextOptions {
36
31
  /**
37
32
  * Content represented by this command context. Custom/headless surfaces may
@@ -41,37 +36,10 @@ export interface CreateViewCommandContextOptions {
41
36
  format?: string;
42
37
  title?: string;
43
38
  data?: unknown;
44
- nav?: ViewNavigationContext;
45
- cursor?: number | null;
46
- selection?: {
47
- start: number;
48
- end: number;
49
- } | null;
50
- /** Caller-owned mode value. Prefer `useProvideViewCommandContext` in React so this is live. */
51
- mode: Mode;
52
- toggledIndices?: Set<number>;
53
39
  reload?: () => void;
54
40
  marks?: Partial<ViewCommandContext["marks"]>;
55
- extras?: Record<string, unknown>;
56
41
  }
57
- export type ProvideViewCommandContextOptions = Omit<CreateViewCommandContextOptions, "mode"> & {
58
- /** Advanced override; normally omitted so the hook injects the live command mode. */
59
- mode?: Mode;
60
- };
61
- export declare function createViewCommandContext({ content, format, title, data, nav, cursor, selection, mode, toggledIndices, reload, marks, extras, }: CreateViewCommandContextOptions): ViewCommandContext;
42
+ export type ProvideViewCommandContextOptions = CreateViewCommandContextOptions;
43
+ export declare function createViewCommandContext({ content, format, title, data, reload, marks, }: CreateViewCommandContextOptions): ViewCommandContext;
62
44
  export declare function useProvideViewCommandContext(options: ProvideViewCommandContextOptions | (() => ProvideViewCommandContextOptions)): void;
63
- interface UseViewCommandContextParams {
64
- content: AnyContent;
65
- nav: NavigationState;
66
- reload: () => void;
67
- providerMarks: MarkSet[];
68
- userMarks: MarkSet[];
69
- setMarkSet: (set: MarkSet) => void;
70
- clearMarkNamespace: (namespace: string) => void;
71
- clearAllUserMarks: () => void;
72
- /** Extra fields merged into the view context (e.g. activeRow, selectedRows for table) */
73
- extras?: Record<string, unknown>;
74
- }
75
- export declare function useViewCommandContext({ content, nav, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, extras, }: UseViewCommandContextParams): void;
76
- export {};
77
45
  //# sourceMappingURL=useViewCommandContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useViewCommandContext.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useViewCommandContext.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,UAAU,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,4CAA4C;IAC5C,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,KAAK,EAAE;QACL,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;QAClC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;QAC3C,QAAQ,EAAE,MAAM,IAAI,CAAA;QACpB,SAAS,EAAE,OAAO,EAAE,CAAA;QACpB,aAAa,EAAE,OAAO,EAAE,CAAA;KACzB,CAAA;CACF;AAED,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,cAAc;QACtB,IAAI,EAAE,kBAAkB,CAAA;KACzB;CACF;AAID,MAAM,WAAW,+BAA+B;IAC9C;;;OAGG;IACH,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAA;CAC7C;AAED,MAAM,MAAM,gCAAgC,GAAG,+BAA+B,CAAA;AAE9E,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,MAAM,EACN,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,GACN,EAAE,+BAA+B,GAAG,kBAAkB,CAwBtD;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,gCAAgC,GAAG,CAAC,MAAM,gCAAgC,CAAC,QAKrF"}
@@ -1,6 +1,6 @@
1
- import { useProvideCommandContextKey, useMode } from "@tooee/commands";
1
+ import { useProvideCommandContextKey } from "@tooee/commands";
2
2
  const noop = () => { };
3
- export function createViewCommandContext({ content, format, title, data, nav, cursor, selection, mode, toggledIndices, reload, marks, extras, }) {
3
+ export function createViewCommandContext({ content, format, title, data, reload, marks, }) {
4
4
  const resolvedFormat = format ?? content?.format ?? "custom";
5
5
  const resolvedContent = content ??
6
6
  {
@@ -9,15 +9,10 @@ export function createViewCommandContext({ content, format, title, data, nav, cu
9
9
  title,
10
10
  };
11
11
  return {
12
- ...extras,
13
12
  content: resolvedContent,
14
13
  format: resolvedFormat,
15
14
  title: title ?? content?.title,
16
15
  data: data ?? ("data" in resolvedContent ? resolvedContent.data : undefined),
17
- cursor: cursor ?? nav?.cursor ?? null,
18
- selection: selection ?? nav?.selection ?? null,
19
- mode,
20
- toggledIndices: toggledIndices ?? nav?.toggledIndices ?? new Set(),
21
16
  reload: reload ?? noop,
22
17
  marks: {
23
18
  setMarkSet: marks?.setMarkSet ?? noop,
@@ -29,28 +24,6 @@ export function createViewCommandContext({ content, format, title, data, nav, cu
29
24
  };
30
25
  }
31
26
  export function useProvideViewCommandContext(options) {
32
- const mode = useMode();
33
- useProvideCommandContextKey("view", () => {
34
- const resolvedOptions = typeof options === "function" ? options() : options;
35
- return createViewCommandContext({
36
- ...resolvedOptions,
37
- mode: resolvedOptions.mode ?? mode,
38
- });
39
- });
40
- }
41
- export function useViewCommandContext({ content, nav, reload, providerMarks, userMarks, setMarkSet, clearMarkNamespace, clearAllUserMarks, extras, }) {
42
- useProvideViewCommandContext({
43
- content,
44
- nav,
45
- reload,
46
- marks: {
47
- setMarkSet,
48
- clearNamespace: clearMarkNamespace,
49
- clearAll: clearAllUserMarks,
50
- userMarks,
51
- providerMarks,
52
- },
53
- extras,
54
- });
27
+ useProvideCommandContextKey("view", () => createViewCommandContext(typeof options === "function" ? options() : options));
55
28
  }
56
29
  //# sourceMappingURL=useViewCommandContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useViewCommandContext.js","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAkCtE,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AA6BrB,MAAM,UAAU,wBAAwB,CAAC,EACvC,OAAO,EACP,MAAM,EACN,KAAK,EACL,IAAI,EACJ,GAAG,EACH,MAAM,EACN,SAAS,EACT,IAAI,EACJ,cAAc,EACd,MAAM,EACN,KAAK,EACL,MAAM,GAC0B;IAChC,MAAM,cAAc,GAAG,MAAM,IAAI,OAAO,EAAE,MAAM,IAAI,QAAQ,CAAA;IAC5D,MAAM,eAAe,GACnB,OAAO;QACN;YACC,MAAM,EAAE,cAAc;YACtB,IAAI;YACJ,KAAK;SACgB,CAAA;IAEzB,OAAO;QACL,GAAG,MAAM;QACT,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK;QAC9B,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,EAAE,MAAM,IAAI,GAAG,EAAE,MAAM,IAAI,IAAI;QACrC,SAAS,EAAE,SAAS,IAAI,GAAG,EAAE,SAAS,IAAI,IAAI;QAC9C,IAAI;QACJ,cAAc,EAAE,cAAc,IAAI,GAAG,EAAE,cAAc,IAAI,IAAI,GAAG,EAAU;QAC1E,MAAM,EAAE,MAAM,IAAI,IAAI;QACtB,KAAK,EAAE;YACL,UAAU,EAAE,KAAK,EAAE,UAAU,IAAI,IAAI;YACrC,cAAc,EAAE,KAAK,EAAE,cAAc,IAAI,IAAI;YAC7C,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,IAAI;YACjC,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE;YACjC,aAAa,EAAE,KAAK,EAAE,aAAa,IAAI,EAAE;SAC1C;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,OAAoF;IAEpF,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,2BAA2B,CAAC,MAAM,EAAE,GAAG,EAAE;QACvC,MAAM,eAAe,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QAC3E,OAAO,wBAAwB,CAAC;YAC9B,GAAG,eAAe;YAClB,IAAI,EAAE,eAAe,CAAC,IAAI,IAAI,IAAI;SACnC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAeD,MAAM,UAAU,qBAAqB,CAAC,EACpC,OAAO,EACP,GAAG,EACH,MAAM,EACN,aAAa,EACb,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,GACsB;IAC5B,4BAA4B,CAAC;QAC3B,OAAO;QACP,GAAG;QACH,MAAM;QACN,KAAK,EAAE;YACL,UAAU;YACV,cAAc,EAAE,kBAAkB;YAClC,QAAQ,EAAE,iBAAiB;YAC3B,SAAS;YACT,aAAa;SACd;QACD,MAAM;KACP,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"useViewCommandContext.js","sourceRoot":"","sources":["../../src/hooks/useViewCommandContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AAiC7D,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAiBrB,MAAM,UAAU,wBAAwB,CAAC,EACvC,OAAO,EACP,MAAM,EACN,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,GAC2B;IAChC,MAAM,cAAc,GAAG,MAAM,IAAI,OAAO,EAAE,MAAM,IAAI,QAAQ,CAAA;IAC5D,MAAM,eAAe,GACnB,OAAO;QACN;YACC,MAAM,EAAE,cAAc;YACtB,IAAI;YACJ,KAAK;SACgB,CAAA;IAEzB,OAAO;QACL,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK;QAC9B,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,EAAE,MAAM,IAAI,IAAI;QACtB,KAAK,EAAE;YACL,UAAU,EAAE,KAAK,EAAE,UAAU,IAAI,IAAI;YACrC,cAAc,EAAE,KAAK,EAAE,cAAc,IAAI,IAAI;YAC7C,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,IAAI;YACjC,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE;YACjC,aAAa,EAAE,KAAK,EAAE,aAAa,IAAI,EAAE;SAC1C;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,OAAoF;IAEpF,2BAA2B,CAAC,MAAM,EAAE,GAAG,EAAE,CACvC,wBAAwB,CAAC,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAC9E,CAAA;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,9 +3,10 @@ export { DirectoryView } from "./DirectoryView.js";
3
3
  export { launch, launchDirectory } from "./launch.js";
4
4
  export type { ViewLaunchOptions } from "./launch.js";
5
5
  export { createFileProvider, createStdinProvider, createTableFileProvider, createTableStdinProvider, } from "./default-provider.js";
6
+ export type { CreateProviderOptions } from "./default-provider.js";
6
7
  export { listDirectoryFiles } from "./directory-provider.js";
7
8
  export type { DirectoryEntry } from "./directory-provider.js";
8
- export { createViewCommandContext, useProvideViewCommandContext, useViewCommandContext, } from "./hooks/useViewCommandContext.js";
9
+ export { createViewCommandContext, useProvideViewCommandContext, } from "./hooks/useViewCommandContext.js";
9
10
  export type { CreateViewCommandContextOptions, ProvideViewCommandContextOptions, ViewCommandContext, } from "./hooks/useViewCommandContext.js";
10
11
  export type { AnyContent, Content, ContentChunk, ContentFormat, ContentProvider, ContentRenderer, ContentRendererProps, CustomContent, ViewContent, ViewContentProvider, ColumnDef, TableRow, } from "./types.js";
11
12
  export { getTextContent, isBuiltinContent, isCustomContent } from "./types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,kCAAkC,CAAA;AACzC,YAAY,EACV,+BAA+B,EAC/B,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,kCAAkC,CAAA;AACzC,YAAY,EACV,UAAU,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,SAAS,EACT,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,kCAAkC,CAAA;AACzC,YAAY,EACV,+BAA+B,EAC/B,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,kCAAkC,CAAA;AACzC,YAAY,EACV,UAAU,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,SAAS,EACT,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export { DirectoryView } from "./DirectoryView.js";
3
3
  export { launch, launchDirectory } from "./launch.js";
4
4
  export { createFileProvider, createStdinProvider, createTableFileProvider, createTableStdinProvider, } from "./default-provider.js";
5
5
  export { listDirectoryFiles } from "./directory-provider.js";
6
- export { createViewCommandContext, useProvideViewCommandContext, useViewCommandContext, } from "./hooks/useViewCommandContext.js";
6
+ export { createViewCommandContext, useProvideViewCommandContext, } from "./hooks/useViewCommandContext.js";
7
7
  export { getTextContent, isBuiltinContent, isCustomContent } from "./types.js";
8
8
  export { CodeBlockChrome } from "@tooee/renderers";
9
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE5D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,kCAAkC,CAAA;AAoBzC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAErD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE5D,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,kCAAkC,CAAA;AAoBzC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA"}
package/dist/types.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { ReactNode } from "react";
2
- import type { ColumnDef, TableRow } from "@tooee/renderers";
3
- import type { MarkSet, MarkState } from "@tooee/marks";
2
+ import type { ColumnDef, SourceLineRow, TableRow } from "@tooee/renderers";
3
+ import type { DocumentController } from "@tooee/shell";
4
+ import type { MarkSet } from "@tooee/marks";
4
5
  export type Content = MarkdownContent | CodeContent | TextContent | TableContent;
5
6
  export type ContentFormat = Content["format"];
6
7
  interface BaseContent {
@@ -35,22 +36,20 @@ export interface CustomContent<T = unknown> {
35
36
  export type AnyContent = Content | CustomContent;
36
37
  export interface ContentRendererProps {
37
38
  content: CustomContent;
38
- lineCount: number;
39
- cursor?: number;
40
- selectionStart?: number;
41
- selectionEnd?: number;
42
- /** Combined mark state (nav + provider + user marks) */
43
- marks?: MarkState;
44
39
  /**
45
- * Select a row by index — the mouse equivalent of the keyboard cursor move.
46
- * A custom renderer that has a notion of rows should call this from its own
47
- * `onMouseDown`/`onRowClick` handlers to make left-click select a row, the
48
- * same way the built-in code/markdown/table views do. Selection is a no-op
49
- * while a modal overlay is open (the host guards it), so renderers can wire
50
- * it unconditionally. Renderers that own a `RowDocumentRenderable` can map a
51
- * click's screen-Y to a row via its `getRowAtScreenY(event.y)` helper.
40
+ * The host's document controller. Its rows are the content's source lines
41
+ * (`SourceLineRow`), which is also the unit navigation, search and copy work
42
+ * in; `row.text` is the plain-text line and `row.source` its provenance.
43
+ *
44
+ * A renderer that owns a `<row-document>` binds the controller directly — it
45
+ * satisfies `DocumentBindings`, so `ref`, `decorations` and `onMouseDown`
46
+ * spread onto the element the way the built-in views wire them. A renderer
47
+ * with its own markup reads `activeIndex` and `navigation.selection` for
48
+ * cursor state and calls `selectRow(index)` from its mouse handlers;
49
+ * `selectRow` stands down while a modal overlay is open, so it can be wired
50
+ * unconditionally.
52
51
  */
53
- onSelectRow?: (index: number) => void;
52
+ document: DocumentController<SourceLineRow>;
54
53
  }
55
54
  export type ContentRenderer = (props: ContentRendererProps) => ReactNode;
56
55
  export type AppendableFormat = Extract<ContentFormat, "markdown" | "code" | "text">;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAiHA,oBAAoB;AAEpB,MAAM,eAAe,GAAgB,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAEnF,MAAM,UAAU,gBAAgB,CAAC,OAAmB;IAClD,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAmB;IAChD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,cAAc,EAAE,CAAA;IACjC,CAAC;IAED,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAA;IACX,CAAC;IAED,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,UAAU;YACb,OAAO,OAAO,CAAC,QAAQ,CAAA;QACzB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAA;QACrB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAA;QACrB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3E,CAAA;YACD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrD,CAAC;QACD;YACE,OAAO,EAAE,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACjF,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAgHA,oBAAoB;AAEpB,MAAM,eAAe,GAAgB,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAEnF,MAAM,UAAU,gBAAgB,CAAC,OAAmB;IAClD,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAmB;IAChD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,cAAc,EAAE,CAAA;IACjC,CAAC;IAED,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAA;IACX,CAAC;IAED,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,UAAU;YACb,OAAO,OAAO,CAAC,QAAQ,CAAA;QACzB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAA;QACrB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAA;QACrB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3E,CAAA;YACD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrD,CAAC;QACD;YACE,OAAO,EAAE,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACjF,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tooee/view",
3
- "version": "0.1.22",
3
+ "version": "0.2.0",
4
4
  "description": "Terminal content viewer for markdown, code, text, and tables",
5
5
  "keywords": [
6
6
  "cli",
@@ -37,27 +37,27 @@
37
37
  "typecheck": "tsc --noEmit"
38
38
  },
39
39
  "dependencies": {
40
- "@tooee/commands": "0.1.22",
41
- "@tooee/config": "0.1.22",
42
- "@tooee/layout": "0.1.22",
43
- "@tooee/marks": "0.1.22",
44
- "@tooee/overlays": "0.1.22",
45
- "@tooee/renderers": "0.1.22",
46
- "@tooee/search": "0.1.22",
47
- "@tooee/shell": "0.1.22",
48
- "@tooee/themes": "0.1.22",
40
+ "@tooee/commands": "0.2.0",
41
+ "@tooee/config": "0.2.0",
42
+ "@tooee/layout": "0.2.0",
43
+ "@tooee/marks": "0.2.0",
44
+ "@tooee/overlays": "0.2.0",
45
+ "@tooee/renderers": "0.2.0",
46
+ "@tooee/search": "0.2.0",
47
+ "@tooee/shell": "0.2.0",
48
+ "@tooee/themes": "0.2.0",
49
49
  "marked": "^17.0.4"
50
50
  },
51
51
  "devDependencies": {
52
- "@opentui/core": "^0.2.15",
53
- "@opentui/react": "^0.2.15",
52
+ "@opentui/core": "^0.4.3",
53
+ "@opentui/react": "^0.4.3",
54
54
  "@types/bun": "^1.3.10",
55
55
  "@types/react": "^19.2.14",
56
56
  "typescript": "^5.9.3"
57
57
  },
58
58
  "peerDependencies": {
59
- "@opentui/core": "^0.2.15",
60
- "@opentui/react": "^0.2.15",
59
+ "@opentui/core": "^0.4.3",
60
+ "@opentui/react": "^0.4.3",
61
61
  "react": "^18.0.0 || ^19.0.0"
62
62
  }
63
63
  }
package/src/View.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { useState, useCallback } from "react"
1
+ import { useCallback, useMemo, useState } from "react"
2
2
  import { useTheme } from "@tooee/themes"
3
3
  import type { ActionDefinition } from "@tooee/commands"
4
4
  import type { MarkSet } from "@tooee/marks"
@@ -50,6 +50,10 @@ export function View({ contentProvider, actions, renderers, codeBlockRenderers }
50
50
  setUserMarks([])
51
51
  }, [])
52
52
 
53
+ // Mark sets are decoration layers; the controller composes them with the
54
+ // interaction layers it generates, ordered by each set's own priority.
55
+ const decorations = useMemo(() => [...providerMarks, ...userMarks], [providerMarks, userMarks])
56
+
53
57
  if (error) {
54
58
  return (
55
59
  <box style={{ flexDirection: "column" }}>
@@ -67,6 +71,7 @@ export function View({ contentProvider, actions, renderers, codeBlockRenderers }
67
71
  }
68
72
 
69
73
  const shared = {
74
+ decorations,
70
75
  providerMarks,
71
76
  userMarks,
72
77
  setMarkSet,
@@ -0,0 +1,76 @@
1
+ import type { ReactNode } from "react"
2
+ import type { ActionDefinition } from "@tooee/commands"
3
+ import type { StatusBarItem } from "@tooee/layout"
4
+ import type { MarkSet } from "@tooee/marks"
5
+ import { DocumentScreen, type DocumentController } from "@tooee/shell"
6
+ import { useProvideViewCommandContext } from "../hooks/useViewCommandContext.js"
7
+ import type { AnyContent } from "../types.js"
8
+
9
+ export interface ViewScreenProps<T> {
10
+ content: AnyContent
11
+ controller: DocumentController<T>
12
+ streaming: boolean
13
+ actions?: ActionDefinition[]
14
+ /** Content-shaped status (format, line/row counts), rendered before Mode. */
15
+ statusItems?: StatusBarItem[]
16
+ reload: () => void
17
+ providerMarks: MarkSet[]
18
+ userMarks: MarkSet[]
19
+ setMarkSet: (set: MarkSet) => void
20
+ clearMarkNamespace: (namespace: string) => void
21
+ clearAllUserMarks: () => void
22
+ children: ReactNode
23
+ }
24
+
25
+ /**
26
+ * The chrome every subview shares: `DocumentScreen` for the row-document half
27
+ * (theme/quit commands, actions, `ctx.document`, layout, standard status) plus
28
+ * the content-only `ctx.view` slice that viewers contribute on top.
29
+ */
30
+ export function ViewScreen<T>({
31
+ content,
32
+ controller,
33
+ streaming,
34
+ actions,
35
+ statusItems,
36
+ reload,
37
+ providerMarks,
38
+ userMarks,
39
+ setMarkSet,
40
+ clearMarkNamespace,
41
+ clearAllUserMarks,
42
+ children,
43
+ }: ViewScreenProps<T>) {
44
+ useProvideViewCommandContext({
45
+ content,
46
+ reload,
47
+ marks: {
48
+ setMarkSet,
49
+ clearNamespace: clearMarkNamespace,
50
+ clearAll: clearAllUserMarks,
51
+ userMarks,
52
+ providerMarks,
53
+ },
54
+ })
55
+
56
+ const items: StatusBarItem[] = [
57
+ ...(statusItems ?? []),
58
+ ...(streaming ? [{ label: "Status:", value: "streaming" }] : []),
59
+ ]
60
+
61
+ return (
62
+ <DocumentScreen
63
+ controller={controller}
64
+ titleBar={
65
+ content.title
66
+ ? { title: content.title, subtitle: content.format }
67
+ : { title: content.format }
68
+ }
69
+ statusItems={items}
70
+ actions={actions}
71
+ context={{ kind: content.format, title: content.title, reload }}
72
+ >
73
+ {children}
74
+ </DocumentScreen>
75
+ )
76
+ }
@@ -1,143 +1,53 @@
1
- import { useCallback, useEffect, useMemo, useRef } from "react"
2
- import { CodeView, type RowDocumentRenderable } from "@tooee/renderers"
3
- import { useTheme } from "@tooee/themes"
4
- import { useCommandContext } from "@tooee/commands"
5
- import { useHasModalOverlay } from "@tooee/overlays"
6
- import { useViewCommandContext } from "../../hooks/useViewCommandContext.js"
7
- import { actionsToContextMenuEntries, useContextMenu, useCopy, useNavigation } from "@tooee/shell"
8
- import { findMatchingLines, useSearch } from "@tooee/search"
1
+ import { useMemo } from "react"
2
+ import { CodeView, sourceLines, sourceLineAdapter, type SourceLineRow } from "@tooee/renderers"
3
+ import { actionsToContextMenuEntries, useDocumentController } from "@tooee/shell"
9
4
  import type { CodeContent, TextContent } from "../../types.js"
10
- import { useMarkState } from "../../hooks/useMarkState.js"
11
- import { useViewCommands } from "../../hooks/useViewCommands.js"
12
- import { SubviewLayout } from "../SubviewLayout.js"
5
+ import { useContentCommands } from "../../hooks/useContentCommands.js"
6
+ import { ViewScreen } from "../ViewScreen.js"
13
7
  import type { SubviewProps } from "./types.js"
14
8
 
15
9
  interface CodeSubviewProps extends SubviewProps {
16
10
  content: CodeContent | TextContent
17
11
  }
18
12
 
19
- export function CodeSubview({
20
- content,
21
- providerMarks,
22
- userMarks,
23
- setMarkSet,
24
- clearMarkNamespace,
25
- clearAllUserMarks,
26
- reload,
27
- streaming,
28
- actions,
29
- }: CodeSubviewProps) {
30
- const { theme } = useTheme()
31
- const docRef = useRef<RowDocumentRenderable>(null)
32
- const hasModalOverlay = useHasModalOverlay()
33
- const contextMenu = useContextMenu()
34
- const { invoke } = useCommandContext()
13
+ export function CodeSubview({ content, decorations, actions, ...screen }: CodeSubviewProps) {
35
14
  const textContent = content.format === "code" ? content.code : content.text
36
- const lines = useMemo(() => textContent.split("\n"), [textContent])
37
- const lineCount = lines.length
15
+ // One navigation row per physical source line; row index is the source line.
16
+ const lineRows = useMemo(() => sourceLines(textContent), [textContent])
38
17
 
39
- const nav = useNavigation({
40
- rowCount: lineCount,
41
- multiSelect: true,
42
- })
43
- const search = useSearch({
44
- match: (query) => findMatchingLines(textContent, query),
45
- onJump: nav.setCursor,
46
- })
47
- useCopy({
48
- getRowText: (index) => lines[index] ?? "",
49
- cursor: nav.cursor,
50
- selection: nav.selection,
51
- toggledIndices: nav.toggledIndices,
52
- })
53
- const layoutNav = { ...nav, ...search }
54
-
55
- useEffect(() => {
56
- if (nav.cursor !== null) {
57
- docRef.current?.scrollToRow(nav.cursor, "nearest")
58
- }
59
- }, [nav.cursor])
60
-
61
- const { themeName, showLineNumbers } = useViewCommands({ content, textContent, actions })
62
-
63
- const markState = useMarkState({
64
- nav,
65
- search,
66
- theme,
67
- providerMarks,
68
- userMarks,
69
- })
18
+ const { showLineNumbers } = useContentCommands({ content, textContent })
19
+ const contextMenu = useMemo(() => actionsToContextMenuEntries(actions), [actions])
70
20
 
71
- useViewCommandContext({
72
- content,
73
- nav,
74
- reload,
75
- providerMarks,
76
- userMarks,
77
- setMarkSet,
78
- clearMarkNamespace,
79
- clearAllUserMarks,
21
+ const document = useDocumentController<SourceLineRow>({
22
+ rows: lineRows,
23
+ adapter: sourceLineAdapter,
24
+ multiSelect: true,
25
+ decorations,
26
+ contextMenu,
80
27
  })
81
28
 
82
- const text = content.format === "code" ? content.code : content.text
83
-
84
- const menuEntries = useMemo(() => actionsToContextMenuEntries(actions), [actions])
85
-
86
- // Left-click selects the clicked line; right-click selects it and opens the
87
- // same app-provided action menu as table rows. Both stand down while a modal
88
- // overlay is up (theme picker, command palette, Ask/Choose), matching the
89
- // keyboard stand-down and avoiding covered-app mutations.
90
- const setCursor = nav.setCursor
91
- const openContextMenu = contextMenu.open
92
- const handleRowClick = useCallback(
93
- (index: number) => {
94
- if (hasModalOverlay) return
95
- setCursor(index)
96
- },
97
- [hasModalOverlay, setCursor],
98
- )
99
- const handleRowContextMenu = useCallback(
100
- (index: number, x: number, y: number) => {
101
- if (hasModalOverlay) return
102
- setCursor(index)
103
- openContextMenu(x, y, menuEntries, invoke)
104
- },
105
- [hasModalOverlay, setCursor, openContextMenu, menuEntries, invoke],
106
- )
107
-
108
- const extraStatusItems = useMemo(() => {
109
- const selectionCount = nav.selection != null ? nav.selection.end - nav.selection.start + 1 : 0
110
- const toggledCount = nav.toggledIndices.size
111
- const selectionItems =
112
- toggledCount > 0
113
- ? [{ label: "Selected:", value: String(toggledCount) }]
114
- : selectionCount > 0
115
- ? [{ label: "Selected:", value: String(selectionCount) }]
116
- : []
117
- return [
29
+ const statusItems = useMemo(
30
+ () => [
118
31
  { label: "Format:", value: content.format },
119
- { label: "Lines:", value: String(lineCount) },
120
- ...selectionItems,
121
- ]
122
- }, [content.format, lineCount, nav.selection, nav.toggledIndices])
32
+ { label: "Lines:", value: String(lineRows.length) },
33
+ ],
34
+ [content.format, lineRows.length],
35
+ )
123
36
 
124
37
  return (
125
- <SubviewLayout
38
+ <ViewScreen
126
39
  content={content}
127
- nav={layoutNav}
128
- streaming={streaming}
129
- themeName={themeName}
130
- extraStatusItems={extraStatusItems}
40
+ controller={document}
41
+ actions={actions}
42
+ statusItems={statusItems}
43
+ {...screen}
131
44
  >
132
45
  <CodeView
133
- content={text}
46
+ content={textContent}
134
47
  language={content.format === "code" ? content.language : undefined}
135
48
  showLineNumbers={showLineNumbers}
136
- marks={markState}
137
- docRef={docRef}
138
- onRowClick={handleRowClick}
139
- onRowContextMenu={handleRowContextMenu}
49
+ document={document}
140
50
  />
141
- </SubviewLayout>
51
+ </ViewScreen>
142
52
  )
143
53
  }