@tutti-os/workspace-file-preview 0.0.219 → 0.0.221

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,6 +15,8 @@ This package ships:
15
15
  - `createWorkspaceFilePreviewController` for shared frontend loading lifecycle
16
16
  (readiness, cancellation, stale-request fencing, decoding, object-URL cleanup)
17
17
  - Built-in React preview shells for `image` / `video` / `text`
18
+ - `WorkspaceImagePreviewSurface` for reusing the built-in image canvas while
19
+ keeping source loading, URL lifetime, and error policy in the host
18
20
  - Host renderer registry (by `previewKind`) and a resolve chain:
19
21
  host hook → text degradation → unsupported state
20
22
  - `toSurfaceState(controllerState, copy)` to project controller state into the
@@ -1,5 +1,5 @@
1
1
  import { WorkspaceFilePreviewKind, WorkspaceFilePreviewReadonlyReason, WorkspaceFilePreviewUnsupportedReason, WorkspaceFilePreviewControllerState } from '../core/index.js';
2
- import { ReactNode, ReactElement } from 'react';
2
+ import { ReactNode, ReactElement, ImgHTMLAttributes } from 'react';
3
3
 
4
4
  /**
5
5
  * Thin built-in preview surface (image / video / text) plus host renderer hooks.
@@ -57,6 +57,18 @@ type WorkspaceFilePreviewSurfaceState<TEntry> = {
57
57
  status: "error";
58
58
  };
59
59
  type WorkspaceFilePreviewSurfaceVariant = "canvas" | "compact" | "detail";
60
+ /**
61
+ * Host-neutral image canvas shared by workspace previews and other file-backed
62
+ * surfaces. The caller owns the source URL lifecycle and error-state policy.
63
+ */
64
+ interface WorkspaceImagePreviewSurfaceProps {
65
+ alt: string;
66
+ draggable?: boolean;
67
+ onError?: ImgHTMLAttributes<HTMLImageElement>["onError"];
68
+ src: string;
69
+ variant: WorkspaceFilePreviewSurfaceVariant;
70
+ }
71
+ declare function WorkspaceImagePreviewSurface({ alt, draggable, onError, src, variant }: WorkspaceImagePreviewSurfaceProps): ReactElement;
60
72
  interface WorkspaceFilePreviewHostRendererProps<TEntry> {
61
73
  entry: TEntry;
62
74
  previewKind: WorkspaceFilePreviewKind;
@@ -109,4 +121,4 @@ interface WorkspaceFilePreviewSurfaceCopy {
109
121
  */
110
122
  declare function toSurfaceState<TEntry>(state: WorkspaceFilePreviewControllerState<TEntry>, copy: WorkspaceFilePreviewSurfaceCopy): WorkspaceFilePreviewSurfaceState<TEntry>;
111
123
 
112
- export { type WorkspaceFilePreviewHostRenderer, type WorkspaceFilePreviewHostRendererProps, type WorkspaceFilePreviewHostRenderers, WorkspaceFilePreviewSurface, type WorkspaceFilePreviewSurfaceCopy, type WorkspaceFilePreviewSurfaceProps, type WorkspaceFilePreviewSurfaceState, type WorkspaceFilePreviewSurfaceVariant, toSurfaceState };
124
+ export { type WorkspaceFilePreviewHostRenderer, type WorkspaceFilePreviewHostRendererProps, type WorkspaceFilePreviewHostRenderers, WorkspaceFilePreviewSurface, type WorkspaceFilePreviewSurfaceCopy, type WorkspaceFilePreviewSurfaceProps, type WorkspaceFilePreviewSurfaceState, type WorkspaceFilePreviewSurfaceVariant, WorkspaceImagePreviewSurface, type WorkspaceImagePreviewSurfaceProps, toSurfaceState };
@@ -66,6 +66,31 @@ function toSurfaceState(state, copy) {
66
66
 
67
67
  // src/react/workspaceFilePreviewSurface.tsx
68
68
  import { jsx, jsxs } from "react/jsx-runtime";
69
+ function WorkspaceImagePreviewSurface({
70
+ alt,
71
+ draggable,
72
+ onError,
73
+ src,
74
+ variant
75
+ }) {
76
+ const styles = workspaceFilePreviewSurfaceStyles[variant];
77
+ return /* @__PURE__ */ jsx(
78
+ WorkspaceFilePreviewFrame,
79
+ {
80
+ className: joinClassNames(styles.frame, styles.imageFrame),
81
+ children: /* @__PURE__ */ jsx(
82
+ "img",
83
+ {
84
+ alt,
85
+ className: styles.image,
86
+ draggable,
87
+ onError,
88
+ src
89
+ }
90
+ )
91
+ }
92
+ );
93
+ }
69
94
  function WorkspaceFilePreviewSurface({
70
95
  directoryMessage,
71
96
  emptyMessage,
@@ -99,17 +124,11 @@ function WorkspaceFilePreviewSurface({
99
124
  ] }) });
100
125
  case "image":
101
126
  return /* @__PURE__ */ jsx(
102
- WorkspaceFilePreviewFrame,
127
+ WorkspaceImagePreviewSurface,
103
128
  {
104
- className: joinClassNames(styles.frame, styles.imageFrame),
105
- children: /* @__PURE__ */ jsx(
106
- "img",
107
- {
108
- alt: imageAlt(state.entry),
109
- className: styles.image,
110
- src: state.objectUrl
111
- }
112
- )
129
+ alt: imageAlt(state.entry),
130
+ src: state.objectUrl,
131
+ variant
113
132
  }
114
133
  );
115
134
  case "text":
@@ -242,6 +261,7 @@ function joinClassNames(...classNames) {
242
261
  }
243
262
  export {
244
263
  WorkspaceFilePreviewSurface,
264
+ WorkspaceImagePreviewSurface,
245
265
  toSurfaceState
246
266
  };
247
267
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/toSurfaceState.ts","../../src/react/workspaceFilePreviewSurface.tsx"],"sourcesContent":["/**\n * Projects controller state into surface state with host-provided copy.\n *\n * Ownership rules: packages/workspace/file-preview/CONTRACT.md\n */\n\nimport type {\n WorkspaceFilePreviewControllerState,\n WorkspaceFilePreviewUnsupportedReason\n} from \"../core/workspaceFilePreviewController.ts\";\nimport type { WorkspaceFilePreviewReadonlyReason } from \"../core/workspaceFilePreview.ts\";\nimport type { WorkspaceFilePreviewKind } from \"../core/workspaceFilePreviewKinds.ts\";\nimport type { WorkspaceFilePreviewSurfaceState } from \"./workspaceFilePreviewSurface.tsx\";\n\nexport interface WorkspaceFilePreviewSurfaceCopy {\n errorMessage: (error: unknown) => string;\n readonlyMessage: (\n reason: WorkspaceFilePreviewReadonlyReason,\n maxSizeBytes?: number\n ) => string;\n unsupportedMessage: (\n reason: WorkspaceFilePreviewUnsupportedReason,\n previewKind?: WorkspaceFilePreviewKind\n ) => string;\n}\n\n/**\n * Shared projection from machine-readable controller state to the React\n * surface state. Controllers remain the source of truth; hosts inject copy.\n */\nexport function toSurfaceState<TEntry>(\n state: WorkspaceFilePreviewControllerState<TEntry>,\n copy: WorkspaceFilePreviewSurfaceCopy\n): WorkspaceFilePreviewSurfaceState<TEntry> {\n switch (state.status) {\n case \"empty\":\n return { status: \"empty\" };\n case \"directory\":\n return { entry: state.entry, status: \"directory\" };\n case \"loading\":\n return {\n entry: state.entry,\n previewKind: state.previewKind,\n status: \"loading\"\n };\n case \"text\":\n return {\n content: state.content,\n entry: state.entry,\n previewKind: state.previewKind,\n status: \"text\"\n };\n case \"image\":\n return {\n entry: state.entry,\n objectUrl: state.objectUrl,\n previewKind: \"image\",\n status: \"image\"\n };\n case \"video\":\n return {\n entry: state.entry,\n objectUrl: state.objectUrl,\n previewKind: \"video\",\n status: \"video\"\n };\n case \"bytes\":\n return {\n bytes: state.bytes,\n contentType: state.contentType,\n entry: state.entry,\n previewKind: state.previewKind,\n status: \"bytes\"\n };\n case \"readonly\":\n return {\n entry: state.entry,\n message: copy.readonlyMessage(state.reason, state.maxSizeBytes),\n previewKind: state.previewKind,\n status: \"readonly\"\n };\n case \"unsupported\":\n return {\n entry: state.entry,\n message: copy.unsupportedMessage(state.reason, state.previewKind),\n previewKind: state.previewKind,\n status: \"unsupported\"\n };\n case \"error\":\n return {\n entry: state.entry,\n message: copy.errorMessage(state.error),\n previewKind: state.previewKind,\n status: \"error\"\n };\n }\n}\n","/**\n * Thin built-in preview surface (image / video / text) plus host renderer hooks.\n *\n * Resolve order: host renderer for previewKind → built-in text degradation →\n * unsupported/fallback messaging already present in state.\n *\n * Ownership rules: packages/workspace/file-preview/CONTRACT.md\n */\n\nimport type { ReactElement, ReactNode } from \"react\";\nimport type { WorkspaceFilePreviewKind } from \"../core/workspaceFilePreviewKinds.ts\";\n\nexport type WorkspaceFilePreviewSurfaceState<TEntry> =\n | { status: \"empty\" }\n | { entry: TEntry; status: \"directory\" }\n | {\n entry: TEntry;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"loading\";\n }\n | {\n content: string;\n entry: TEntry;\n previewKind: WorkspaceFilePreviewKind;\n status: \"text\";\n }\n | {\n entry: TEntry;\n objectUrl: string;\n previewKind: \"image\";\n status: \"image\";\n }\n | {\n entry: TEntry;\n objectUrl: string;\n previewKind: \"video\";\n status: \"video\";\n }\n | {\n bytes: Uint8Array<ArrayBuffer>;\n contentType: string | null;\n entry: TEntry;\n previewKind: WorkspaceFilePreviewKind;\n status: \"bytes\";\n }\n | {\n entry: TEntry;\n message: string;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"readonly\";\n }\n | {\n entry: TEntry;\n message: string;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"unsupported\";\n }\n | {\n entry: TEntry;\n message: string;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"error\";\n };\n\nexport type WorkspaceFilePreviewSurfaceVariant =\n | \"canvas\"\n | \"compact\"\n | \"detail\";\n\nexport interface WorkspaceFilePreviewHostRendererProps<TEntry> {\n entry: TEntry;\n previewKind: WorkspaceFilePreviewKind;\n variant: WorkspaceFilePreviewSurfaceVariant;\n /** Present when the controller decoded text (including text-degradable kinds). */\n content?: string;\n /** Present for hook-only kinds loaded as raw bytes. */\n bytes?: Uint8Array<ArrayBuffer>;\n contentType?: string | null;\n /** Present for built-in media kinds when a host still overrides rendering. */\n objectUrl?: string;\n}\n\nexport type WorkspaceFilePreviewHostRenderer<TEntry> = (\n props: WorkspaceFilePreviewHostRendererProps<TEntry>\n) => ReactNode;\n\n/**\n * Host renderer registry keyed by previewKind. `variant` is passed as props;\n * optional (kind, variant) specificity may be added later.\n */\nexport type WorkspaceFilePreviewHostRenderers<TEntry> = Partial<\n Record<WorkspaceFilePreviewKind, WorkspaceFilePreviewHostRenderer<TEntry>>\n>;\n\nexport interface WorkspaceFilePreviewSurfaceProps<TEntry> {\n directoryMessage: string;\n emptyMessage: string;\n imageAlt: (entry: TEntry) => string;\n loadingIndicator: ReactNode;\n loadingMessage: string;\n /**\n * Optional host renderers registered by previewKind. When present for the\n * current kind, they win over built-in image / video / text shells.\n */\n renderers?: WorkspaceFilePreviewHostRenderers<TEntry>;\n renderIcon: (entry: TEntry) => ReactNode;\n state: WorkspaceFilePreviewSurfaceState<TEntry>;\n variant: WorkspaceFilePreviewSurfaceVariant;\n}\n\nexport function WorkspaceFilePreviewSurface<TEntry>({\n directoryMessage,\n emptyMessage,\n imageAlt,\n loadingIndicator,\n loadingMessage,\n renderers,\n renderIcon,\n state,\n variant\n}: WorkspaceFilePreviewSurfaceProps<TEntry>): ReactElement {\n const styles = workspaceFilePreviewSurfaceStyles[variant];\n const hostRendered = renderHostPreview({\n renderers,\n state,\n variant\n });\n if (hostRendered !== null) {\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n {hostRendered}\n </WorkspaceFilePreviewFrame>\n );\n }\n\n switch (state.status) {\n case \"directory\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"flex flex-col items-center justify-center gap-2.5 text-center text-[13px] leading-5 text-[var(--text-tertiary)]\">\n {renderIcon(state.entry)}\n <span>{directoryMessage}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"loading\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"space-y-3 px-4 text-center text-[13px] text-[var(--text-tertiary)]\">\n {loadingIndicator}\n <span>{loadingMessage}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"image\":\n return (\n <WorkspaceFilePreviewFrame\n className={joinClassNames(styles.frame, styles.imageFrame)}\n >\n <img\n alt={imageAlt(state.entry)}\n className={styles.image}\n src={state.objectUrl}\n />\n </WorkspaceFilePreviewFrame>\n );\n case \"text\":\n return (\n <WorkspaceFilePreviewFrame\n className={joinClassNames(styles.frame, styles.textFrame)}\n >\n <pre className={styles.text}>{state.content}</pre>\n </WorkspaceFilePreviewFrame>\n );\n case \"video\":\n return (\n <WorkspaceFilePreviewFrame\n className={joinClassNames(styles.frame, styles.videoFrame)}\n >\n <video\n aria-label={imageAlt(state.entry)}\n className={styles.video}\n muted\n playsInline\n preload=\"metadata\"\n src={state.objectUrl}\n onLoadedMetadata={(event) => {\n const video = event.currentTarget;\n if (video.duration > 0 && video.currentTime === 0) {\n video.currentTime = Math.min(0.1, video.duration / 2);\n }\n }}\n />\n </WorkspaceFilePreviewFrame>\n );\n case \"bytes\":\n // Hook-only kinds without a registered renderer fall through to the\n // unsupported messaging path via host-projected state; if bytes somehow\n // arrive without a hook, show the generic unsupported shell.\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"flex flex-col items-center justify-center gap-3 px-4 text-center text-[13px] text-[var(--text-tertiary)]\">\n {renderIcon(state.entry)}\n <span className={styles.message}>{emptyMessage}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"readonly\":\n case \"unsupported\":\n case \"error\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"flex flex-col items-center justify-center gap-3 px-4 text-center text-[13px] text-[var(--text-tertiary)]\">\n {renderIcon(state.entry)}\n <span className={styles.message}>{state.message}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"empty\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <span className={styles.message}>{emptyMessage}</span>\n </WorkspaceFilePreviewFrame>\n );\n }\n}\n\nfunction renderHostPreview<TEntry>(input: {\n renderers: WorkspaceFilePreviewHostRenderers<TEntry> | undefined;\n state: WorkspaceFilePreviewSurfaceState<TEntry>;\n variant: WorkspaceFilePreviewSurfaceVariant;\n}): ReactNode | null {\n const { renderers, state, variant } = input;\n if (!renderers) {\n return null;\n }\n\n switch (state.status) {\n case \"text\": {\n const renderer = renderers[state.previewKind];\n return renderer\n ? renderer({\n content: state.content,\n entry: state.entry,\n previewKind: state.previewKind,\n variant\n })\n : null;\n }\n case \"image\":\n case \"video\": {\n const renderer = renderers[state.previewKind];\n return renderer\n ? renderer({\n entry: state.entry,\n objectUrl: state.objectUrl,\n previewKind: state.previewKind,\n variant\n })\n : null;\n }\n case \"bytes\": {\n const renderer = renderers[state.previewKind];\n return renderer\n ? renderer({\n bytes: state.bytes,\n contentType: state.contentType,\n entry: state.entry,\n previewKind: state.previewKind,\n variant\n })\n : null;\n }\n default:\n return null;\n }\n}\n\nconst workspaceFilePreviewSurfaceStyles: Record<\n WorkspaceFilePreviewSurfaceVariant,\n {\n frame: string;\n image: string;\n imageFrame: string;\n message: string;\n text: string;\n textFrame: string;\n video: string;\n videoFrame: string;\n }\n> = {\n compact: {\n frame:\n \"flex aspect-[3/2] w-full flex-col items-center justify-center overflow-hidden rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)] p-0 text-center\",\n image: \"max-h-full max-w-full rounded-[6px] object-contain\",\n imageFrame: \"p-3\",\n message:\n \"mx-auto max-w-[24ch] text-center text-[13px] leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]\",\n text: \"h-full w-full overflow-auto p-3 text-left text-[11px] leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]\",\n textFrame: \"items-stretch justify-stretch\",\n video: \"block max-h-full max-w-full rounded-[6px] object-contain\",\n videoFrame: \"p-3\"\n },\n detail: {\n frame:\n \"flex h-60 min-h-60 max-h-60 items-center justify-center overflow-hidden rounded-lg bg-[var(--transparency-block)]\",\n image: \"max-h-full max-w-full rounded-[6px] object-contain\",\n imageFrame: \"p-4\",\n message:\n \"max-w-[24ch] text-center text-[13px] leading-5 text-[var(--text-tertiary)] [overflow-wrap:anywhere]\",\n text: \"h-full overflow-auto p-4 text-[11px] leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]\",\n textFrame: \"items-stretch justify-stretch\",\n video: \"block max-h-full max-w-full rounded-[6px] object-contain\",\n videoFrame: \"p-4\"\n },\n canvas: {\n frame:\n \"flex h-full min-h-0 min-w-0 w-full items-center justify-center overflow-hidden bg-[var(--background-fronted)] text-[var(--text-tertiary)]\",\n image: \"block max-h-full max-w-full object-contain\",\n imageFrame: \"overflow-auto p-3\",\n message:\n \"max-w-[24ch] text-center text-[13px] leading-5 text-[var(--text-tertiary)] [overflow-wrap:anywhere]\",\n text: \"m-0 h-full min-h-0 min-w-0 w-full overflow-auto whitespace-pre-wrap break-words p-3 font-[var(--tsh-font-mono)] text-[11px] leading-[18px] text-[var(--text-secondary)]\",\n textFrame: \"items-stretch justify-stretch\",\n video: \"block max-h-full max-w-full object-contain\",\n videoFrame: \"overflow-auto p-3\"\n }\n};\n\nfunction WorkspaceFilePreviewFrame({\n children,\n className\n}: {\n children: ReactNode;\n className: string;\n}): ReactElement {\n return <div className={className}>{children}</div>;\n}\n\nfunction joinClassNames(\n ...classNames: Array<string | false | null | undefined>\n): string {\n return classNames.filter(Boolean).join(\" \");\n}\n"],"mappings":";AA8BO,SAAS,eACd,OACA,MAC0C;AAC1C,UAAQ,MAAM,QAAQ;AAAA,IACpB,KAAK;AACH,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B,KAAK;AACH,aAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,YAAY;AAAA,IACnD,KAAK;AACH,aAAO;AAAA,QACL,OAAO,MAAM;AAAA,QACb,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,QACb,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,MAAM;AAAA,QACb,WAAW,MAAM;AAAA,QACjB,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,MAAM;AAAA,QACb,WAAW,MAAM;AAAA,QACjB,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,MAAM;AAAA,QACb,aAAa,MAAM;AAAA,QACnB,OAAO,MAAM;AAAA,QACb,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,MAAM;AAAA,QACb,SAAS,KAAK,gBAAgB,MAAM,QAAQ,MAAM,YAAY;AAAA,QAC9D,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,MAAM;AAAA,QACb,SAAS,KAAK,mBAAmB,MAAM,QAAQ,MAAM,WAAW;AAAA,QAChE,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,MAAM;AAAA,QACb,SAAS,KAAK,aAAa,MAAM,KAAK;AAAA,QACtC,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,MACV;AAAA,EACJ;AACF;;;ACiCM,cAUI,YAVJ;AAnBC,SAAS,4BAAoC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2D;AACzD,QAAM,SAAS,kCAAkC,OAAO;AACxD,QAAM,eAAe,kBAAkB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,iBAAiB,MAAM;AACzB,WACE,oBAAC,6BAA0B,WAAW,OAAO,OAC1C,wBACH;AAAA,EAEJ;AAEA,UAAQ,MAAM,QAAQ;AAAA,IACpB,KAAK;AACH,aACE,oBAAC,6BAA0B,WAAW,OAAO,OAC3C,+BAAC,SAAI,WAAU,mHACZ;AAAA,mBAAW,MAAM,KAAK;AAAA,QACvB,oBAAC,UAAM,4BAAiB;AAAA,SAC1B,GACF;AAAA,IAEJ,KAAK;AACH,aACE,oBAAC,6BAA0B,WAAW,OAAO,OAC3C,+BAAC,SAAI,WAAU,sEACZ;AAAA;AAAA,QACD,oBAAC,UAAM,0BAAe;AAAA,SACxB,GACF;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,eAAe,OAAO,OAAO,OAAO,UAAU;AAAA,UAEzD;AAAA,YAAC;AAAA;AAAA,cACC,KAAK,SAAS,MAAM,KAAK;AAAA,cACzB,WAAW,OAAO;AAAA,cAClB,KAAK,MAAM;AAAA;AAAA,UACb;AAAA;AAAA,MACF;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,eAAe,OAAO,OAAO,OAAO,SAAS;AAAA,UAExD,8BAAC,SAAI,WAAW,OAAO,MAAO,gBAAM,SAAQ;AAAA;AAAA,MAC9C;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,eAAe,OAAO,OAAO,OAAO,UAAU;AAAA,UAEzD;AAAA,YAAC;AAAA;AAAA,cACC,cAAY,SAAS,MAAM,KAAK;AAAA,cAChC,WAAW,OAAO;AAAA,cAClB,OAAK;AAAA,cACL,aAAW;AAAA,cACX,SAAQ;AAAA,cACR,KAAK,MAAM;AAAA,cACX,kBAAkB,CAAC,UAAU;AAC3B,sBAAM,QAAQ,MAAM;AACpB,oBAAI,MAAM,WAAW,KAAK,MAAM,gBAAgB,GAAG;AACjD,wBAAM,cAAc,KAAK,IAAI,KAAK,MAAM,WAAW,CAAC;AAAA,gBACtD;AAAA,cACF;AAAA;AAAA,UACF;AAAA;AAAA,MACF;AAAA,IAEJ,KAAK;AAIH,aACE,oBAAC,6BAA0B,WAAW,OAAO,OAC3C,+BAAC,SAAI,WAAU,4GACZ;AAAA,mBAAW,MAAM,KAAK;AAAA,QACvB,oBAAC,UAAK,WAAW,OAAO,SAAU,wBAAa;AAAA,SACjD,GACF;AAAA,IAEJ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aACE,oBAAC,6BAA0B,WAAW,OAAO,OAC3C,+BAAC,SAAI,WAAU,4GACZ;AAAA,mBAAW,MAAM,KAAK;AAAA,QACvB,oBAAC,UAAK,WAAW,OAAO,SAAU,gBAAM,SAAQ;AAAA,SAClD,GACF;AAAA,IAEJ,KAAK;AACH,aACE,oBAAC,6BAA0B,WAAW,OAAO,OAC3C,8BAAC,UAAK,WAAW,OAAO,SAAU,wBAAa,GACjD;AAAA,EAEN;AACF;AAEA,SAAS,kBAA0B,OAId;AACnB,QAAM,EAAE,WAAW,OAAO,QAAQ,IAAI;AACtC,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,UAAQ,MAAM,QAAQ;AAAA,IACpB,KAAK,QAAQ;AACX,YAAM,WAAW,UAAU,MAAM,WAAW;AAC5C,aAAO,WACH,SAAS;AAAA,QACP,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,QACb,aAAa,MAAM;AAAA,QACnB;AAAA,MACF,CAAC,IACD;AAAA,IACN;AAAA,IACA,KAAK;AAAA,IACL,KAAK,SAAS;AACZ,YAAM,WAAW,UAAU,MAAM,WAAW;AAC5C,aAAO,WACH,SAAS;AAAA,QACP,OAAO,MAAM;AAAA,QACb,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,QACnB;AAAA,MACF,CAAC,IACD;AAAA,IACN;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,WAAW,UAAU,MAAM,WAAW;AAC5C,aAAO,WACH,SAAS;AAAA,QACP,OAAO,MAAM;AAAA,QACb,aAAa,MAAM;AAAA,QACnB,OAAO,MAAM;AAAA,QACb,aAAa,MAAM;AAAA,QACnB;AAAA,MACF,CAAC,IACD;AAAA,IACN;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAEA,IAAM,oCAYF;AAAA,EACF,SAAS;AAAA,IACP,OACE;AAAA,IACF,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SACE;AAAA,IACF,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AAAA,EACA,QAAQ;AAAA,IACN,OACE;AAAA,IACF,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SACE;AAAA,IACF,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AAAA,EACA,QAAQ;AAAA,IACN,OACE;AAAA,IACF,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SACE;AAAA,IACF,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AACF;AAEA,SAAS,0BAA0B;AAAA,EACjC;AAAA,EACA;AACF,GAGiB;AACf,SAAO,oBAAC,SAAI,WAAuB,UAAS;AAC9C;AAEA,SAAS,kBACJ,YACK;AACR,SAAO,WAAW,OAAO,OAAO,EAAE,KAAK,GAAG;AAC5C;","names":[]}
1
+ {"version":3,"sources":["../../src/react/toSurfaceState.ts","../../src/react/workspaceFilePreviewSurface.tsx"],"sourcesContent":["/**\n * Projects controller state into surface state with host-provided copy.\n *\n * Ownership rules: packages/workspace/file-preview/CONTRACT.md\n */\n\nimport type {\n WorkspaceFilePreviewControllerState,\n WorkspaceFilePreviewUnsupportedReason\n} from \"../core/workspaceFilePreviewController.ts\";\nimport type { WorkspaceFilePreviewReadonlyReason } from \"../core/workspaceFilePreview.ts\";\nimport type { WorkspaceFilePreviewKind } from \"../core/workspaceFilePreviewKinds.ts\";\nimport type { WorkspaceFilePreviewSurfaceState } from \"./workspaceFilePreviewSurface.tsx\";\n\nexport interface WorkspaceFilePreviewSurfaceCopy {\n errorMessage: (error: unknown) => string;\n readonlyMessage: (\n reason: WorkspaceFilePreviewReadonlyReason,\n maxSizeBytes?: number\n ) => string;\n unsupportedMessage: (\n reason: WorkspaceFilePreviewUnsupportedReason,\n previewKind?: WorkspaceFilePreviewKind\n ) => string;\n}\n\n/**\n * Shared projection from machine-readable controller state to the React\n * surface state. Controllers remain the source of truth; hosts inject copy.\n */\nexport function toSurfaceState<TEntry>(\n state: WorkspaceFilePreviewControllerState<TEntry>,\n copy: WorkspaceFilePreviewSurfaceCopy\n): WorkspaceFilePreviewSurfaceState<TEntry> {\n switch (state.status) {\n case \"empty\":\n return { status: \"empty\" };\n case \"directory\":\n return { entry: state.entry, status: \"directory\" };\n case \"loading\":\n return {\n entry: state.entry,\n previewKind: state.previewKind,\n status: \"loading\"\n };\n case \"text\":\n return {\n content: state.content,\n entry: state.entry,\n previewKind: state.previewKind,\n status: \"text\"\n };\n case \"image\":\n return {\n entry: state.entry,\n objectUrl: state.objectUrl,\n previewKind: \"image\",\n status: \"image\"\n };\n case \"video\":\n return {\n entry: state.entry,\n objectUrl: state.objectUrl,\n previewKind: \"video\",\n status: \"video\"\n };\n case \"bytes\":\n return {\n bytes: state.bytes,\n contentType: state.contentType,\n entry: state.entry,\n previewKind: state.previewKind,\n status: \"bytes\"\n };\n case \"readonly\":\n return {\n entry: state.entry,\n message: copy.readonlyMessage(state.reason, state.maxSizeBytes),\n previewKind: state.previewKind,\n status: \"readonly\"\n };\n case \"unsupported\":\n return {\n entry: state.entry,\n message: copy.unsupportedMessage(state.reason, state.previewKind),\n previewKind: state.previewKind,\n status: \"unsupported\"\n };\n case \"error\":\n return {\n entry: state.entry,\n message: copy.errorMessage(state.error),\n previewKind: state.previewKind,\n status: \"error\"\n };\n }\n}\n","/**\n * Thin built-in preview surface (image / video / text) plus host renderer hooks.\n *\n * Resolve order: host renderer for previewKind → built-in text degradation →\n * unsupported/fallback messaging already present in state.\n *\n * Ownership rules: packages/workspace/file-preview/CONTRACT.md\n */\n\nimport type { ImgHTMLAttributes, ReactElement, ReactNode } from \"react\";\nimport type { WorkspaceFilePreviewKind } from \"../core/workspaceFilePreviewKinds.ts\";\n\nexport type WorkspaceFilePreviewSurfaceState<TEntry> =\n | { status: \"empty\" }\n | { entry: TEntry; status: \"directory\" }\n | {\n entry: TEntry;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"loading\";\n }\n | {\n content: string;\n entry: TEntry;\n previewKind: WorkspaceFilePreviewKind;\n status: \"text\";\n }\n | {\n entry: TEntry;\n objectUrl: string;\n previewKind: \"image\";\n status: \"image\";\n }\n | {\n entry: TEntry;\n objectUrl: string;\n previewKind: \"video\";\n status: \"video\";\n }\n | {\n bytes: Uint8Array<ArrayBuffer>;\n contentType: string | null;\n entry: TEntry;\n previewKind: WorkspaceFilePreviewKind;\n status: \"bytes\";\n }\n | {\n entry: TEntry;\n message: string;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"readonly\";\n }\n | {\n entry: TEntry;\n message: string;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"unsupported\";\n }\n | {\n entry: TEntry;\n message: string;\n previewKind?: WorkspaceFilePreviewKind;\n status: \"error\";\n };\n\nexport type WorkspaceFilePreviewSurfaceVariant =\n | \"canvas\"\n | \"compact\"\n | \"detail\";\n\n/**\n * Host-neutral image canvas shared by workspace previews and other file-backed\n * surfaces. The caller owns the source URL lifecycle and error-state policy.\n */\nexport interface WorkspaceImagePreviewSurfaceProps {\n alt: string;\n draggable?: boolean;\n onError?: ImgHTMLAttributes<HTMLImageElement>[\"onError\"];\n src: string;\n variant: WorkspaceFilePreviewSurfaceVariant;\n}\n\nexport function WorkspaceImagePreviewSurface({\n alt,\n draggable,\n onError,\n src,\n variant\n}: WorkspaceImagePreviewSurfaceProps): ReactElement {\n const styles = workspaceFilePreviewSurfaceStyles[variant];\n return (\n <WorkspaceFilePreviewFrame\n className={joinClassNames(styles.frame, styles.imageFrame)}\n >\n <img\n alt={alt}\n className={styles.image}\n draggable={draggable}\n onError={onError}\n src={src}\n />\n </WorkspaceFilePreviewFrame>\n );\n}\n\nexport interface WorkspaceFilePreviewHostRendererProps<TEntry> {\n entry: TEntry;\n previewKind: WorkspaceFilePreviewKind;\n variant: WorkspaceFilePreviewSurfaceVariant;\n /** Present when the controller decoded text (including text-degradable kinds). */\n content?: string;\n /** Present for hook-only kinds loaded as raw bytes. */\n bytes?: Uint8Array<ArrayBuffer>;\n contentType?: string | null;\n /** Present for built-in media kinds when a host still overrides rendering. */\n objectUrl?: string;\n}\n\nexport type WorkspaceFilePreviewHostRenderer<TEntry> = (\n props: WorkspaceFilePreviewHostRendererProps<TEntry>\n) => ReactNode;\n\n/**\n * Host renderer registry keyed by previewKind. `variant` is passed as props;\n * optional (kind, variant) specificity may be added later.\n */\nexport type WorkspaceFilePreviewHostRenderers<TEntry> = Partial<\n Record<WorkspaceFilePreviewKind, WorkspaceFilePreviewHostRenderer<TEntry>>\n>;\n\nexport interface WorkspaceFilePreviewSurfaceProps<TEntry> {\n directoryMessage: string;\n emptyMessage: string;\n imageAlt: (entry: TEntry) => string;\n loadingIndicator: ReactNode;\n loadingMessage: string;\n /**\n * Optional host renderers registered by previewKind. When present for the\n * current kind, they win over built-in image / video / text shells.\n */\n renderers?: WorkspaceFilePreviewHostRenderers<TEntry>;\n renderIcon: (entry: TEntry) => ReactNode;\n state: WorkspaceFilePreviewSurfaceState<TEntry>;\n variant: WorkspaceFilePreviewSurfaceVariant;\n}\n\nexport function WorkspaceFilePreviewSurface<TEntry>({\n directoryMessage,\n emptyMessage,\n imageAlt,\n loadingIndicator,\n loadingMessage,\n renderers,\n renderIcon,\n state,\n variant\n}: WorkspaceFilePreviewSurfaceProps<TEntry>): ReactElement {\n const styles = workspaceFilePreviewSurfaceStyles[variant];\n const hostRendered = renderHostPreview({\n renderers,\n state,\n variant\n });\n if (hostRendered !== null) {\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n {hostRendered}\n </WorkspaceFilePreviewFrame>\n );\n }\n\n switch (state.status) {\n case \"directory\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"flex flex-col items-center justify-center gap-2.5 text-center text-[13px] leading-5 text-[var(--text-tertiary)]\">\n {renderIcon(state.entry)}\n <span>{directoryMessage}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"loading\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"space-y-3 px-4 text-center text-[13px] text-[var(--text-tertiary)]\">\n {loadingIndicator}\n <span>{loadingMessage}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"image\":\n return (\n <WorkspaceImagePreviewSurface\n alt={imageAlt(state.entry)}\n src={state.objectUrl}\n variant={variant}\n />\n );\n case \"text\":\n return (\n <WorkspaceFilePreviewFrame\n className={joinClassNames(styles.frame, styles.textFrame)}\n >\n <pre className={styles.text}>{state.content}</pre>\n </WorkspaceFilePreviewFrame>\n );\n case \"video\":\n return (\n <WorkspaceFilePreviewFrame\n className={joinClassNames(styles.frame, styles.videoFrame)}\n >\n <video\n aria-label={imageAlt(state.entry)}\n className={styles.video}\n muted\n playsInline\n preload=\"metadata\"\n src={state.objectUrl}\n onLoadedMetadata={(event) => {\n const video = event.currentTarget;\n if (video.duration > 0 && video.currentTime === 0) {\n video.currentTime = Math.min(0.1, video.duration / 2);\n }\n }}\n />\n </WorkspaceFilePreviewFrame>\n );\n case \"bytes\":\n // Hook-only kinds without a registered renderer fall through to the\n // unsupported messaging path via host-projected state; if bytes somehow\n // arrive without a hook, show the generic unsupported shell.\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"flex flex-col items-center justify-center gap-3 px-4 text-center text-[13px] text-[var(--text-tertiary)]\">\n {renderIcon(state.entry)}\n <span className={styles.message}>{emptyMessage}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"readonly\":\n case \"unsupported\":\n case \"error\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <div className=\"flex flex-col items-center justify-center gap-3 px-4 text-center text-[13px] text-[var(--text-tertiary)]\">\n {renderIcon(state.entry)}\n <span className={styles.message}>{state.message}</span>\n </div>\n </WorkspaceFilePreviewFrame>\n );\n case \"empty\":\n return (\n <WorkspaceFilePreviewFrame className={styles.frame}>\n <span className={styles.message}>{emptyMessage}</span>\n </WorkspaceFilePreviewFrame>\n );\n }\n}\n\nfunction renderHostPreview<TEntry>(input: {\n renderers: WorkspaceFilePreviewHostRenderers<TEntry> | undefined;\n state: WorkspaceFilePreviewSurfaceState<TEntry>;\n variant: WorkspaceFilePreviewSurfaceVariant;\n}): ReactNode | null {\n const { renderers, state, variant } = input;\n if (!renderers) {\n return null;\n }\n\n switch (state.status) {\n case \"text\": {\n const renderer = renderers[state.previewKind];\n return renderer\n ? renderer({\n content: state.content,\n entry: state.entry,\n previewKind: state.previewKind,\n variant\n })\n : null;\n }\n case \"image\":\n case \"video\": {\n const renderer = renderers[state.previewKind];\n return renderer\n ? renderer({\n entry: state.entry,\n objectUrl: state.objectUrl,\n previewKind: state.previewKind,\n variant\n })\n : null;\n }\n case \"bytes\": {\n const renderer = renderers[state.previewKind];\n return renderer\n ? renderer({\n bytes: state.bytes,\n contentType: state.contentType,\n entry: state.entry,\n previewKind: state.previewKind,\n variant\n })\n : null;\n }\n default:\n return null;\n }\n}\n\nconst workspaceFilePreviewSurfaceStyles: Record<\n WorkspaceFilePreviewSurfaceVariant,\n {\n frame: string;\n image: string;\n imageFrame: string;\n message: string;\n text: string;\n textFrame: string;\n video: string;\n videoFrame: string;\n }\n> = {\n compact: {\n frame:\n \"flex aspect-[3/2] w-full flex-col items-center justify-center overflow-hidden rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)] p-0 text-center\",\n image: \"max-h-full max-w-full rounded-[6px] object-contain\",\n imageFrame: \"p-3\",\n message:\n \"mx-auto max-w-[24ch] text-center text-[13px] leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]\",\n text: \"h-full w-full overflow-auto p-3 text-left text-[11px] leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]\",\n textFrame: \"items-stretch justify-stretch\",\n video: \"block max-h-full max-w-full rounded-[6px] object-contain\",\n videoFrame: \"p-3\"\n },\n detail: {\n frame:\n \"flex h-60 min-h-60 max-h-60 items-center justify-center overflow-hidden rounded-lg bg-[var(--transparency-block)]\",\n image: \"max-h-full max-w-full rounded-[6px] object-contain\",\n imageFrame: \"p-4\",\n message:\n \"max-w-[24ch] text-center text-[13px] leading-5 text-[var(--text-tertiary)] [overflow-wrap:anywhere]\",\n text: \"h-full overflow-auto p-4 text-[11px] leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]\",\n textFrame: \"items-stretch justify-stretch\",\n video: \"block max-h-full max-w-full rounded-[6px] object-contain\",\n videoFrame: \"p-4\"\n },\n canvas: {\n frame:\n \"flex h-full min-h-0 min-w-0 w-full items-center justify-center overflow-hidden bg-[var(--background-fronted)] text-[var(--text-tertiary)]\",\n image: \"block max-h-full max-w-full object-contain\",\n imageFrame: \"overflow-auto p-3\",\n message:\n \"max-w-[24ch] text-center text-[13px] leading-5 text-[var(--text-tertiary)] [overflow-wrap:anywhere]\",\n text: \"m-0 h-full min-h-0 min-w-0 w-full overflow-auto whitespace-pre-wrap break-words p-3 font-[var(--tsh-font-mono)] text-[11px] leading-[18px] text-[var(--text-secondary)]\",\n textFrame: \"items-stretch justify-stretch\",\n video: \"block max-h-full max-w-full object-contain\",\n videoFrame: \"overflow-auto p-3\"\n }\n};\n\nfunction WorkspaceFilePreviewFrame({\n children,\n className\n}: {\n children: ReactNode;\n className: string;\n}): ReactElement {\n return <div className={className}>{children}</div>;\n}\n\nfunction joinClassNames(\n ...classNames: Array<string | false | null | undefined>\n): string {\n return classNames.filter(Boolean).join(\" \");\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tutti-os/workspace-file-preview",
3
- "version": "0.0.219",
3
+ "version": "0.0.221",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",