@ai-matrx/design-system 0.21.6 → 0.21.7

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-table/host.tsx"],"sourcesContent":["\"use client\";\nimport { createContext, useContext, type Context, type ComponentType, type ReactNode, type MouseEventHandler } from \"react\";\nimport type { CopyControlProps } from \"./copy-types\";\nimport type { MatrxDataTableDensity, MatrxDataTableRecordControls, TableSavedViewsProps } from \"./types\";\n\nexport type {\n AgentPayloadInput,\n AiCustomSource,\n AiVariant,\n CopyControlProps,\n CopyExportConfig,\n} from \"./copy-types\";\n\nexport interface TableLinkProps { href: string; children: ReactNode; className?: string; onClick?: MouseEventHandler<HTMLAnchorElement>; }\n/**\n * Host-owned toolbar affordance. The table package keeps operation state and\n * labels; an application can supply its canonical icon-button primitive\n * without making the shared package depend on an application UI package.\n */\nexport interface TableToolbarActionProps { ariaLabel: string; tooltip?: string | undefined; disabled?: boolean | undefined; busy?: boolean | undefined; /** Indicates a selected mutually-exclusive action such as the current page. */ active?: boolean | undefined; onClick: () => void; children: ReactNode; }\nexport interface TableSidePanelProps { title: string; titleNode?: ReactNode; description?: ReactNode; onClose: () => void; defaultWidth?: number; headerActions?: ReactNode; children: ReactNode; }\nexport interface TableWindowPanelProps { id: string; title: string; onClose: () => void; width?: number; height?: number; minWidth?: number; minHeight?: number; actionsRight?: ReactNode; bodyClassName?: string; sidebarDefaultSize?: number; sidebarMinSize?: number; sidebar?: ReactNode; children: ReactNode; }\nexport interface TableEntityRefProps { token: string; id: string; href?: string; children: ReactNode; className?: string; }\nexport interface TablePeekProps { kind: string; id: string; href?: string; onClose: () => void; }\nexport interface TableDoors { href?: string; peekKind?: string; canPeek?: boolean; }\nexport interface TableRowContextRegistry { register(tableId: string, resolve: (rowId: string) => unknown): () => void; }\nexport interface TableContextMenuBoundaryProps { label: string; children: ReactNode; }\nexport interface MatrxDataTableHost { JsonViewer?: ComponentType<{ data: object | string }>; Link?: ComponentType<TableLinkProps>; CopyControls?: ComponentType<CopyControlProps>; ToolbarAction?: ComponentType<TableToolbarActionProps>; SidePanelSurface?: ComponentType<TableSidePanelProps>; WindowPanel?: ComponentType<TableWindowPanelProps>; EntityRef?: ComponentType<TableEntityRefProps>; resolveEntityDoors?: (token: string, id: string, href?: string | null) => TableDoors | null; ResourcePeek?: ComponentType<TablePeekProps>; SavedViews?: ComponentType<TableSavedViewsProps>; rowContextRegistry?: TableRowContextRegistry; createDefaultRowContext?: (row: unknown, controls: import(\"./types\").MatrxDataTableRecordControls) => unknown; ContextMenuBoundary?: ComponentType<TableContextMenuBoundaryProps>; /** Host default; a table's explicit density takes precedence. */ defaultDensity?: MatrxDataTableDensity; notify?: { success(message: string): void; error(message: string): void }; }\n// Public entrypoints are independently bundled in ESM and CJS. The context\n// identity must survive those bundle boundaries; values stay provider-scoped.\nconst HOST_SLOT = Symbol.for(\"ai-matrx.design-system.table-host-context\");\nconst hostRegistry = globalThis as typeof globalThis & { [HOST_SLOT]?: Context<MatrxDataTableHost> };\nconst HostContext = hostRegistry[HOST_SLOT] ??= createContext<MatrxDataTableHost>({});\nexport function MatrxDataTableProvider({ value, children }: { value: MatrxDataTableHost; children: ReactNode }) { return <HostContext.Provider value={value}>{children}</HostContext.Provider>; }\nexport function useMatrxDataTableHost(): MatrxDataTableHost { return useContext(HostContext); }\n\nexport interface MatrxTableRowAlchemy {\n copy: CopyControlProps;\n controls?: MatrxDataTableRecordControls;\n placement: \"inline\" | \"menu\";\n ready: boolean;\n activate(): void;\n prepare(restoreFocus?: () => void): Promise<void>;\n}\n\nconst ROW_ALCHEMY_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-alchemy-context\");\nconst rowAlchemyRegistry = globalThis as typeof globalThis & { [ROW_ALCHEMY_SLOT]?: Context<MatrxTableRowAlchemy | null> };\nconst RowAlchemyContext = rowAlchemyRegistry[ROW_ALCHEMY_SLOT] ??= createContext<MatrxTableRowAlchemy | null>(null);\n\nexport function MatrxTableRowAlchemyScope({ value, children }: { value: MatrxTableRowAlchemy; children: ReactNode }) { return <RowAlchemyContext.Provider value={value}>{children}</RowAlchemyContext.Provider>; }\n\nexport function useMatrxTableRowAlchemy(): MatrxTableRowAlchemy | null { return useContext(RowAlchemyContext); }\n\nconst ROW_CONTROLS_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-controls-context\");\nconst rowControlsRegistry = globalThis as typeof globalThis & { [ROW_CONTROLS_SLOT]?: Context<MatrxDataTableRecordControls | null> };\nconst RowControlsContext = rowControlsRegistry[ROW_CONTROLS_SLOT] ??= createContext<MatrxDataTableRecordControls | null>(null);\nexport function MatrxTableRowControlsScope({ value, children }: { value: MatrxDataTableRecordControls; children: ReactNode }) { return <RowControlsContext.Provider value={value}>{children}</RowControlsContext.Provider>; }\nexport function useMatrxTableRowControls(): MatrxDataTableRecordControls | null { return useContext(RowControlsContext); }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAoH;AAgCK;AAHzH,IAAM,YAAY,uBAAO,IAAI,2CAA2C;AACxE,IAAM,eAAe;AACrB,IAAM,cAAc,aAAa,SAAS,UAAM,4BAAkC,CAAC,CAAC;AAC7E,SAAS,uBAAuB,EAAE,OAAO,SAAS,GAAuD;AAAE,SAAO,4CAAC,YAAY,UAAZ,EAAqB,OAAe,UAAS;AAAyB;AACzL,SAAS,wBAA4C;AAAE,aAAO,yBAAW,WAAW;AAAG;AAW9F,IAAM,mBAAmB,uBAAO,IAAI,kDAAkD;AACtF,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB,mBAAmB,gBAAgB,UAAM,4BAA2C,IAAI;AAE3G,SAAS,0BAA0B,EAAE,OAAO,SAAS,GAAyD;AAAE,SAAO,4CAAC,kBAAkB,UAAlB,EAA2B,OAAe,UAAS;AAA+B;AAE1M,SAAS,0BAAuD;AAAE,aAAO,yBAAW,iBAAiB;AAAG;AAE/G,IAAM,oBAAoB,uBAAO,IAAI,mDAAmD;AACxF,IAAM,sBAAsB;AAC5B,IAAM,qBAAqB,oBAAoB,iBAAiB,UAAM,4BAAmD,IAAI;AACtH,SAAS,2BAA2B,EAAE,OAAO,SAAS,GAAiE;AAAE,SAAO,4CAAC,mBAAmB,UAAnB,EAA4B,OAAe,UAAS;AAAgC;AACrN,SAAS,2BAAgE;AAAE,aAAO,yBAAW,kBAAkB;AAAG;","names":[]}
1
+ {"version":3,"sources":["../../src/data-table/host.tsx"],"sourcesContent":["\"use client\";\nimport { createContext, useContext, type Context, type ComponentType, type ReactNode, type MouseEventHandler } from \"react\";\nimport type { CopyControlProps } from \"./copy-types\";\nimport type { MatrxDataTableDensity, MatrxDataTableRecordControls, TableSavedViewsProps } from \"./types\";\n\nexport type {\n AgentPayloadInput,\n AiCustomSource,\n AiVariant,\n CopyControlProps,\n CopyExportConfig,\n} from \"./copy-types\";\n\nexport interface TableLinkProps { href: string; children: ReactNode; className?: string; onClick?: MouseEventHandler<HTMLAnchorElement>; }\n/**\n * Host-owned toolbar affordance. The table package keeps operation state and\n * labels; an application can supply its canonical icon-button primitive\n * without making the shared package depend on an application UI package.\n */\nexport interface TableToolbarActionProps { ariaLabel: string; tooltip?: string | undefined; disabled?: boolean | undefined; busy?: boolean | undefined; /** Indicates a selected mutually-exclusive action such as the current page. */ active?: boolean | undefined; onClick: () => void; children: ReactNode; }\nexport interface TableSidePanelProps { title: string; titleNode?: ReactNode; description?: ReactNode; onClose: () => void; defaultWidth?: number; headerActions?: ReactNode; children: ReactNode; }\nexport interface TableWindowPanelProps { id: string; title: string; onClose: () => void; width?: number; height?: number; minWidth?: number; minHeight?: number; actionsRight?: ReactNode; bodyClassName?: string; sidebarDefaultSize?: number; sidebarMinSize?: number; sidebar?: ReactNode; children: ReactNode; }\nexport interface TableEntityRefProps { token: string; id: string; href?: string; children: ReactNode; className?: string; }\nexport interface TablePeekProps { kind: string; id: string; href?: string; onClose: () => void; }\nexport interface TableDoors { href?: string; peekKind?: string; canPeek?: boolean; }\nexport interface TableRowContextRegistry { register(tableId: string, resolve: (rowId: string) => unknown): () => void; }\nexport interface TableContextMenuBoundaryProps { label: string; children: ReactNode; }\nexport interface MatrxDataTableHost { JsonViewer?: ComponentType<{ data: object | string }>; Link?: ComponentType<TableLinkProps>; CopyControls?: ComponentType<CopyControlProps>; ToolbarAction?: ComponentType<TableToolbarActionProps>; SidePanelSurface?: ComponentType<TableSidePanelProps>; WindowPanel?: ComponentType<TableWindowPanelProps>; EntityRef?: ComponentType<TableEntityRefProps>; resolveEntityDoors?: (token: string, id: string, href?: string | null) => TableDoors | null; ResourcePeek?: ComponentType<TablePeekProps>; SavedViews?: ComponentType<TableSavedViewsProps>; rowContextRegistry?: TableRowContextRegistry; createDefaultRowContext?: (row: unknown, controls: import(\"./types\").MatrxDataTableRecordControls) => unknown; ContextMenuBoundary?: ComponentType<TableContextMenuBoundaryProps>; /** Host default; a table's explicit density takes precedence. */ defaultDensity?: MatrxDataTableDensity; notify?: { success(message: string): void; error(message: string): void }; }\n// Public entrypoints are independently bundled in ESM and CJS. The context\n// identity must survive those bundle boundaries; values stay provider-scoped.\nconst HOST_SLOT = Symbol.for(\"ai-matrx.design-system.table-host-context\");\nconst hostRegistry = globalThis as typeof globalThis & { [HOST_SLOT]?: Context<MatrxDataTableHost> };\nconst HostContext = hostRegistry[HOST_SLOT] ??= createContext<MatrxDataTableHost>({});\nexport function MatrxDataTableProvider({ value, children }: { value: MatrxDataTableHost; children: ReactNode }) { return <HostContext.Provider value={value}>{children}</HostContext.Provider>; }\nexport function useMatrxDataTableHost(): MatrxDataTableHost { return useContext(HostContext); }\n\nexport interface MatrxTableRowAlchemy {\n copy: CopyControlProps;\n controls?: MatrxDataTableRecordControls;\n placement: \"inline\" | \"menu\";\n ready: boolean;\n activate(): void;\n /** Mount Alchemy's canonical palette in the host row menu. */\n mountMenu(target: HTMLElement | null, onClose?: () => void, restoreFocus?: () => void): void;\n prepare(restoreFocus?: () => void): Promise<void>;\n}\n\nconst ROW_ALCHEMY_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-alchemy-context\");\nconst rowAlchemyRegistry = globalThis as typeof globalThis & { [ROW_ALCHEMY_SLOT]?: Context<MatrxTableRowAlchemy | null> };\nconst RowAlchemyContext = rowAlchemyRegistry[ROW_ALCHEMY_SLOT] ??= createContext<MatrxTableRowAlchemy | null>(null);\n\nexport function MatrxTableRowAlchemyScope({ value, children }: { value: MatrxTableRowAlchemy; children: ReactNode }) { return <RowAlchemyContext.Provider value={value}>{children}</RowAlchemyContext.Provider>; }\n\nexport function useMatrxTableRowAlchemy(): MatrxTableRowAlchemy | null { return useContext(RowAlchemyContext); }\n\nconst ROW_CONTROLS_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-controls-context\");\nconst rowControlsRegistry = globalThis as typeof globalThis & { [ROW_CONTROLS_SLOT]?: Context<MatrxDataTableRecordControls | null> };\nconst RowControlsContext = rowControlsRegistry[ROW_CONTROLS_SLOT] ??= createContext<MatrxDataTableRecordControls | null>(null);\nexport function MatrxTableRowControlsScope({ value, children }: { value: MatrxDataTableRecordControls; children: ReactNode }) { return <RowControlsContext.Provider value={value}>{children}</RowControlsContext.Provider>; }\nexport function useMatrxTableRowControls(): MatrxDataTableRecordControls | null { return useContext(RowControlsContext); }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAoH;AAgCK;AAHzH,IAAM,YAAY,uBAAO,IAAI,2CAA2C;AACxE,IAAM,eAAe;AACrB,IAAM,cAAc,aAAa,SAAS,UAAM,4BAAkC,CAAC,CAAC;AAC7E,SAAS,uBAAuB,EAAE,OAAO,SAAS,GAAuD;AAAE,SAAO,4CAAC,YAAY,UAAZ,EAAqB,OAAe,UAAS;AAAyB;AACzL,SAAS,wBAA4C;AAAE,aAAO,yBAAW,WAAW;AAAG;AAa9F,IAAM,mBAAmB,uBAAO,IAAI,kDAAkD;AACtF,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB,mBAAmB,gBAAgB,UAAM,4BAA2C,IAAI;AAE3G,SAAS,0BAA0B,EAAE,OAAO,SAAS,GAAyD;AAAE,SAAO,4CAAC,kBAAkB,UAAlB,EAA2B,OAAe,UAAS;AAA+B;AAE1M,SAAS,0BAAuD;AAAE,aAAO,yBAAW,iBAAiB;AAAG;AAE/G,IAAM,oBAAoB,uBAAO,IAAI,mDAAmD;AACxF,IAAM,sBAAsB;AAC5B,IAAM,qBAAqB,oBAAoB,iBAAiB,UAAM,4BAAmD,IAAI;AACtH,SAAS,2BAA2B,EAAE,OAAO,SAAS,GAAiE;AAAE,SAAO,4CAAC,mBAAmB,UAAnB,EAA4B,OAAe,UAAS;AAAgC;AACrN,SAAS,2BAAgE;AAAE,aAAO,yBAAW,kBAAkB;AAAG;","names":[]}
@@ -109,6 +109,8 @@ interface MatrxTableRowAlchemy {
109
109
  placement: "inline" | "menu";
110
110
  ready: boolean;
111
111
  activate(): void;
112
+ /** Mount Alchemy's canonical palette in the host row menu. */
113
+ mountMenu(target: HTMLElement | null, onClose?: () => void, restoreFocus?: () => void): void;
112
114
  prepare(restoreFocus?: () => void): Promise<void>;
113
115
  }
114
116
  declare function MatrxTableRowAlchemyScope({ value, children }: {
@@ -109,6 +109,8 @@ interface MatrxTableRowAlchemy {
109
109
  placement: "inline" | "menu";
110
110
  ready: boolean;
111
111
  activate(): void;
112
+ /** Mount Alchemy's canonical palette in the host row menu. */
113
+ mountMenu(target: HTMLElement | null, onClose?: () => void, restoreFocus?: () => void): void;
112
114
  prepare(restoreFocus?: () => void): Promise<void>;
113
115
  }
114
116
  declare function MatrxTableRowAlchemyScope({ value, children }: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-table/host.tsx"],"sourcesContent":["\"use client\";\nimport { createContext, useContext, type Context, type ComponentType, type ReactNode, type MouseEventHandler } from \"react\";\nimport type { CopyControlProps } from \"./copy-types\";\nimport type { MatrxDataTableDensity, MatrxDataTableRecordControls, TableSavedViewsProps } from \"./types\";\n\nexport type {\n AgentPayloadInput,\n AiCustomSource,\n AiVariant,\n CopyControlProps,\n CopyExportConfig,\n} from \"./copy-types\";\n\nexport interface TableLinkProps { href: string; children: ReactNode; className?: string; onClick?: MouseEventHandler<HTMLAnchorElement>; }\n/**\n * Host-owned toolbar affordance. The table package keeps operation state and\n * labels; an application can supply its canonical icon-button primitive\n * without making the shared package depend on an application UI package.\n */\nexport interface TableToolbarActionProps { ariaLabel: string; tooltip?: string | undefined; disabled?: boolean | undefined; busy?: boolean | undefined; /** Indicates a selected mutually-exclusive action such as the current page. */ active?: boolean | undefined; onClick: () => void; children: ReactNode; }\nexport interface TableSidePanelProps { title: string; titleNode?: ReactNode; description?: ReactNode; onClose: () => void; defaultWidth?: number; headerActions?: ReactNode; children: ReactNode; }\nexport interface TableWindowPanelProps { id: string; title: string; onClose: () => void; width?: number; height?: number; minWidth?: number; minHeight?: number; actionsRight?: ReactNode; bodyClassName?: string; sidebarDefaultSize?: number; sidebarMinSize?: number; sidebar?: ReactNode; children: ReactNode; }\nexport interface TableEntityRefProps { token: string; id: string; href?: string; children: ReactNode; className?: string; }\nexport interface TablePeekProps { kind: string; id: string; href?: string; onClose: () => void; }\nexport interface TableDoors { href?: string; peekKind?: string; canPeek?: boolean; }\nexport interface TableRowContextRegistry { register(tableId: string, resolve: (rowId: string) => unknown): () => void; }\nexport interface TableContextMenuBoundaryProps { label: string; children: ReactNode; }\nexport interface MatrxDataTableHost { JsonViewer?: ComponentType<{ data: object | string }>; Link?: ComponentType<TableLinkProps>; CopyControls?: ComponentType<CopyControlProps>; ToolbarAction?: ComponentType<TableToolbarActionProps>; SidePanelSurface?: ComponentType<TableSidePanelProps>; WindowPanel?: ComponentType<TableWindowPanelProps>; EntityRef?: ComponentType<TableEntityRefProps>; resolveEntityDoors?: (token: string, id: string, href?: string | null) => TableDoors | null; ResourcePeek?: ComponentType<TablePeekProps>; SavedViews?: ComponentType<TableSavedViewsProps>; rowContextRegistry?: TableRowContextRegistry; createDefaultRowContext?: (row: unknown, controls: import(\"./types\").MatrxDataTableRecordControls) => unknown; ContextMenuBoundary?: ComponentType<TableContextMenuBoundaryProps>; /** Host default; a table's explicit density takes precedence. */ defaultDensity?: MatrxDataTableDensity; notify?: { success(message: string): void; error(message: string): void }; }\n// Public entrypoints are independently bundled in ESM and CJS. The context\n// identity must survive those bundle boundaries; values stay provider-scoped.\nconst HOST_SLOT = Symbol.for(\"ai-matrx.design-system.table-host-context\");\nconst hostRegistry = globalThis as typeof globalThis & { [HOST_SLOT]?: Context<MatrxDataTableHost> };\nconst HostContext = hostRegistry[HOST_SLOT] ??= createContext<MatrxDataTableHost>({});\nexport function MatrxDataTableProvider({ value, children }: { value: MatrxDataTableHost; children: ReactNode }) { return <HostContext.Provider value={value}>{children}</HostContext.Provider>; }\nexport function useMatrxDataTableHost(): MatrxDataTableHost { return useContext(HostContext); }\n\nexport interface MatrxTableRowAlchemy {\n copy: CopyControlProps;\n controls?: MatrxDataTableRecordControls;\n placement: \"inline\" | \"menu\";\n ready: boolean;\n activate(): void;\n prepare(restoreFocus?: () => void): Promise<void>;\n}\n\nconst ROW_ALCHEMY_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-alchemy-context\");\nconst rowAlchemyRegistry = globalThis as typeof globalThis & { [ROW_ALCHEMY_SLOT]?: Context<MatrxTableRowAlchemy | null> };\nconst RowAlchemyContext = rowAlchemyRegistry[ROW_ALCHEMY_SLOT] ??= createContext<MatrxTableRowAlchemy | null>(null);\n\nexport function MatrxTableRowAlchemyScope({ value, children }: { value: MatrxTableRowAlchemy; children: ReactNode }) { return <RowAlchemyContext.Provider value={value}>{children}</RowAlchemyContext.Provider>; }\n\nexport function useMatrxTableRowAlchemy(): MatrxTableRowAlchemy | null { return useContext(RowAlchemyContext); }\n\nconst ROW_CONTROLS_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-controls-context\");\nconst rowControlsRegistry = globalThis as typeof globalThis & { [ROW_CONTROLS_SLOT]?: Context<MatrxDataTableRecordControls | null> };\nconst RowControlsContext = rowControlsRegistry[ROW_CONTROLS_SLOT] ??= createContext<MatrxDataTableRecordControls | null>(null);\nexport function MatrxTableRowControlsScope({ value, children }: { value: MatrxDataTableRecordControls; children: ReactNode }) { return <RowControlsContext.Provider value={value}>{children}</RowControlsContext.Provider>; }\nexport function useMatrxTableRowControls(): MatrxDataTableRecordControls | null { return useContext(RowControlsContext); }\n"],"mappings":";;;;AACA,SAAS,eAAe,kBAA4F;AAgCK;AAHzH,IAAM,YAAY,uBAAO,IAAI,2CAA2C;AACxE,IAAM,eAAe;AACrB,IAAM,cAAc,aAAa,SAAS,MAAM,cAAkC,CAAC,CAAC;AAC7E,SAAS,uBAAuB,EAAE,OAAO,SAAS,GAAuD;AAAE,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAe,UAAS;AAAyB;AACzL,SAAS,wBAA4C;AAAE,SAAO,WAAW,WAAW;AAAG;AAW9F,IAAM,mBAAmB,uBAAO,IAAI,kDAAkD;AACtF,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB,mBAAmB,gBAAgB,MAAM,cAA2C,IAAI;AAE3G,SAAS,0BAA0B,EAAE,OAAO,SAAS,GAAyD;AAAE,SAAO,oBAAC,kBAAkB,UAAlB,EAA2B,OAAe,UAAS;AAA+B;AAE1M,SAAS,0BAAuD;AAAE,SAAO,WAAW,iBAAiB;AAAG;AAE/G,IAAM,oBAAoB,uBAAO,IAAI,mDAAmD;AACxF,IAAM,sBAAsB;AAC5B,IAAM,qBAAqB,oBAAoB,iBAAiB,MAAM,cAAmD,IAAI;AACtH,SAAS,2BAA2B,EAAE,OAAO,SAAS,GAAiE;AAAE,SAAO,oBAAC,mBAAmB,UAAnB,EAA4B,OAAe,UAAS;AAAgC;AACrN,SAAS,2BAAgE;AAAE,SAAO,WAAW,kBAAkB;AAAG;","names":[]}
1
+ {"version":3,"sources":["../../src/data-table/host.tsx"],"sourcesContent":["\"use client\";\nimport { createContext, useContext, type Context, type ComponentType, type ReactNode, type MouseEventHandler } from \"react\";\nimport type { CopyControlProps } from \"./copy-types\";\nimport type { MatrxDataTableDensity, MatrxDataTableRecordControls, TableSavedViewsProps } from \"./types\";\n\nexport type {\n AgentPayloadInput,\n AiCustomSource,\n AiVariant,\n CopyControlProps,\n CopyExportConfig,\n} from \"./copy-types\";\n\nexport interface TableLinkProps { href: string; children: ReactNode; className?: string; onClick?: MouseEventHandler<HTMLAnchorElement>; }\n/**\n * Host-owned toolbar affordance. The table package keeps operation state and\n * labels; an application can supply its canonical icon-button primitive\n * without making the shared package depend on an application UI package.\n */\nexport interface TableToolbarActionProps { ariaLabel: string; tooltip?: string | undefined; disabled?: boolean | undefined; busy?: boolean | undefined; /** Indicates a selected mutually-exclusive action such as the current page. */ active?: boolean | undefined; onClick: () => void; children: ReactNode; }\nexport interface TableSidePanelProps { title: string; titleNode?: ReactNode; description?: ReactNode; onClose: () => void; defaultWidth?: number; headerActions?: ReactNode; children: ReactNode; }\nexport interface TableWindowPanelProps { id: string; title: string; onClose: () => void; width?: number; height?: number; minWidth?: number; minHeight?: number; actionsRight?: ReactNode; bodyClassName?: string; sidebarDefaultSize?: number; sidebarMinSize?: number; sidebar?: ReactNode; children: ReactNode; }\nexport interface TableEntityRefProps { token: string; id: string; href?: string; children: ReactNode; className?: string; }\nexport interface TablePeekProps { kind: string; id: string; href?: string; onClose: () => void; }\nexport interface TableDoors { href?: string; peekKind?: string; canPeek?: boolean; }\nexport interface TableRowContextRegistry { register(tableId: string, resolve: (rowId: string) => unknown): () => void; }\nexport interface TableContextMenuBoundaryProps { label: string; children: ReactNode; }\nexport interface MatrxDataTableHost { JsonViewer?: ComponentType<{ data: object | string }>; Link?: ComponentType<TableLinkProps>; CopyControls?: ComponentType<CopyControlProps>; ToolbarAction?: ComponentType<TableToolbarActionProps>; SidePanelSurface?: ComponentType<TableSidePanelProps>; WindowPanel?: ComponentType<TableWindowPanelProps>; EntityRef?: ComponentType<TableEntityRefProps>; resolveEntityDoors?: (token: string, id: string, href?: string | null) => TableDoors | null; ResourcePeek?: ComponentType<TablePeekProps>; SavedViews?: ComponentType<TableSavedViewsProps>; rowContextRegistry?: TableRowContextRegistry; createDefaultRowContext?: (row: unknown, controls: import(\"./types\").MatrxDataTableRecordControls) => unknown; ContextMenuBoundary?: ComponentType<TableContextMenuBoundaryProps>; /** Host default; a table's explicit density takes precedence. */ defaultDensity?: MatrxDataTableDensity; notify?: { success(message: string): void; error(message: string): void }; }\n// Public entrypoints are independently bundled in ESM and CJS. The context\n// identity must survive those bundle boundaries; values stay provider-scoped.\nconst HOST_SLOT = Symbol.for(\"ai-matrx.design-system.table-host-context\");\nconst hostRegistry = globalThis as typeof globalThis & { [HOST_SLOT]?: Context<MatrxDataTableHost> };\nconst HostContext = hostRegistry[HOST_SLOT] ??= createContext<MatrxDataTableHost>({});\nexport function MatrxDataTableProvider({ value, children }: { value: MatrxDataTableHost; children: ReactNode }) { return <HostContext.Provider value={value}>{children}</HostContext.Provider>; }\nexport function useMatrxDataTableHost(): MatrxDataTableHost { return useContext(HostContext); }\n\nexport interface MatrxTableRowAlchemy {\n copy: CopyControlProps;\n controls?: MatrxDataTableRecordControls;\n placement: \"inline\" | \"menu\";\n ready: boolean;\n activate(): void;\n /** Mount Alchemy's canonical palette in the host row menu. */\n mountMenu(target: HTMLElement | null, onClose?: () => void, restoreFocus?: () => void): void;\n prepare(restoreFocus?: () => void): Promise<void>;\n}\n\nconst ROW_ALCHEMY_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-alchemy-context\");\nconst rowAlchemyRegistry = globalThis as typeof globalThis & { [ROW_ALCHEMY_SLOT]?: Context<MatrxTableRowAlchemy | null> };\nconst RowAlchemyContext = rowAlchemyRegistry[ROW_ALCHEMY_SLOT] ??= createContext<MatrxTableRowAlchemy | null>(null);\n\nexport function MatrxTableRowAlchemyScope({ value, children }: { value: MatrxTableRowAlchemy; children: ReactNode }) { return <RowAlchemyContext.Provider value={value}>{children}</RowAlchemyContext.Provider>; }\n\nexport function useMatrxTableRowAlchemy(): MatrxTableRowAlchemy | null { return useContext(RowAlchemyContext); }\n\nconst ROW_CONTROLS_SLOT = Symbol.for(\"ai-matrx.design-system.table-row-controls-context\");\nconst rowControlsRegistry = globalThis as typeof globalThis & { [ROW_CONTROLS_SLOT]?: Context<MatrxDataTableRecordControls | null> };\nconst RowControlsContext = rowControlsRegistry[ROW_CONTROLS_SLOT] ??= createContext<MatrxDataTableRecordControls | null>(null);\nexport function MatrxTableRowControlsScope({ value, children }: { value: MatrxDataTableRecordControls; children: ReactNode }) { return <RowControlsContext.Provider value={value}>{children}</RowControlsContext.Provider>; }\nexport function useMatrxTableRowControls(): MatrxDataTableRecordControls | null { return useContext(RowControlsContext); }\n"],"mappings":";;;;AACA,SAAS,eAAe,kBAA4F;AAgCK;AAHzH,IAAM,YAAY,uBAAO,IAAI,2CAA2C;AACxE,IAAM,eAAe;AACrB,IAAM,cAAc,aAAa,SAAS,MAAM,cAAkC,CAAC,CAAC;AAC7E,SAAS,uBAAuB,EAAE,OAAO,SAAS,GAAuD;AAAE,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAe,UAAS;AAAyB;AACzL,SAAS,wBAA4C;AAAE,SAAO,WAAW,WAAW;AAAG;AAa9F,IAAM,mBAAmB,uBAAO,IAAI,kDAAkD;AACtF,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB,mBAAmB,gBAAgB,MAAM,cAA2C,IAAI;AAE3G,SAAS,0BAA0B,EAAE,OAAO,SAAS,GAAyD;AAAE,SAAO,oBAAC,kBAAkB,UAAlB,EAA2B,OAAe,UAAS;AAA+B;AAE1M,SAAS,0BAAuD;AAAE,SAAO,WAAW,iBAAiB;AAAG;AAE/G,IAAM,oBAAoB,uBAAO,IAAI,mDAAmD;AACxF,IAAM,sBAAsB;AAC5B,IAAM,qBAAqB,oBAAoB,iBAAiB,MAAM,cAAmD,IAAI;AACtH,SAAS,2BAA2B,EAAE,OAAO,SAAS,GAAiE;AAAE,SAAO,oBAAC,mBAAmB,UAAnB,EAA4B,OAAe,UAAS;AAAgC;AACrN,SAAS,2BAAgE;AAAE,SAAO,WAAW,kBAAkB;AAAG;","names":[]}
@@ -3252,6 +3252,10 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
3252
3252
  const [notice, setNotice] = React14.useState(null);
3253
3253
  const [receiptTarget, setReceiptTarget] = React14.useState();
3254
3254
  const [paletteOpen, setPaletteOpen] = React14.useState(false);
3255
+ const [paletteTarget, setPaletteTarget] = React14.useState(null);
3256
+ const externalPaletteClose = React14.useRef(null);
3257
+ const externalPaletteRestoreFocus = React14.useRef(null);
3258
+ const feedbackDocument = React14.useRef(null);
3255
3259
  const [mode, setMode] = React14.useState("copy");
3256
3260
  const scopes = React14.useMemo(() => table?.availableScopes ?? ["target"], [table]);
3257
3261
  const [requestedScope, setRequestedScope] = React14.useState(table?.initialScope ?? "target");
@@ -3348,6 +3352,40 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
3348
3352
  fence.finish(controller);
3349
3353
  }
3350
3354
  }, [captureOne, fence, initialScope, primary]);
3355
+ const closePalette = React14.useCallback(() => {
3356
+ const onClose = externalPaletteClose.current;
3357
+ const restoreFocus = externalPaletteRestoreFocus.current;
3358
+ externalPaletteClose.current = null;
3359
+ externalPaletteRestoreFocus.current = null;
3360
+ onClose?.();
3361
+ restoreFocus?.();
3362
+ setPaletteTarget(null);
3363
+ setPaletteOpen(false);
3364
+ }, []);
3365
+ const mountPalette = React14.useCallback((target, onClose, restoreFocus) => {
3366
+ if (!target) {
3367
+ externalPaletteClose.current = null;
3368
+ externalPaletteRestoreFocus.current = null;
3369
+ setPaletteTarget(null);
3370
+ setPaletteOpen(false);
3371
+ return;
3372
+ }
3373
+ if (!enabled) throw new Error("Alchemy is not enabled for this record.");
3374
+ if (disabled) throw new Error("Alchemy is disabled for this record.");
3375
+ externalPaletteClose.current = onClose ?? null;
3376
+ externalPaletteRestoreFocus.current = restoreFocus ?? null;
3377
+ feedbackDocument.current = target.ownerDocument;
3378
+ restoreFocusRef.current = restoreFocus ?? (() => target.focus());
3379
+ setPaletteTarget(target);
3380
+ setPaletteOpen(true);
3381
+ setMode("copy");
3382
+ void preflight();
3383
+ }, [closePalette, disabled, enabled, preflight]);
3384
+ React14.useEffect(() => {
3385
+ if (!paletteTarget || !paletteOpen) return;
3386
+ const firstControl = paletteTarget.querySelector("button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [href]");
3387
+ firstControl?.focus();
3388
+ }, [paletteOpen, paletteTarget]);
3351
3389
  const transfer = React14.useCallback(async (format, download, alternate) => {
3352
3390
  const { controller, id } = fence.begin();
3353
3391
  try {
@@ -3488,6 +3526,7 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
3488
3526
  );
3489
3527
  React14.useImperativeHandle(controllerRef, () => ({
3490
3528
  focusTrigger: () => triggerRef.current?.focus(),
3529
+ mountPalette,
3491
3530
  preparePrimary: async (options) => {
3492
3531
  if (!enabled) throw new Error("Alchemy is not enabled for this record.");
3493
3532
  if (disabled) throw new Error("Alchemy is disabled for this record.");
@@ -3502,7 +3541,7 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
3502
3541
  externalWorkspaceKeys.current.add(requestedKey);
3503
3542
  await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
3504
3543
  }
3505
- }), [disabled, enabled, hide, openWorkspace, primary, primaryWorkspaceKey, sourceLabel]);
3544
+ }), [disabled, enabled, hide, mountPalette, openWorkspace, primary, primaryWorkspaceKey, sourceLabel]);
3506
3545
  const runAction = React14.useCallback(async (action) => {
3507
3546
  const { controller, id } = fence.begin();
3508
3547
  try {
@@ -3568,7 +3607,6 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
3568
3607
  return (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: (0, import_content_transfer2.buildAgentPayload)({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
3569
3608
  }
3570
3609
  };
3571
- const closePalette = () => setPaletteOpen(false);
3572
3610
  const tile = (id, label2, onClick, options = {}) => {
3573
3611
  const presentation = options.action;
3574
3612
  const Icon3 = presentation?.icon;
@@ -3584,122 +3622,125 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
3584
3622
  ] })
3585
3623
  ] }, id);
3586
3624
  };
3625
+ const palette = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
3626
+ menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
3627
+ table && scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "matrx-alchemy-scope", children: [
3628
+ "Content scope",
3629
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
3630
+ const next = scopes.find((scope) => scope === event.target.value);
3631
+ if (next) {
3632
+ setRequestedScope(next);
3633
+ void preflight(next);
3634
+ }
3635
+ }, children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
3636
+ ] }) : null,
3637
+ copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("section", { className: "matrx-alchemy-output", children: [
3638
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
3639
+ copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
3640
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
3641
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
3642
+ ] }) : null,
3643
+ resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
3644
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
3645
+ visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
3646
+ visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
3647
+ ] }),
3648
+ quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
3649
+ closePalette();
3650
+ void transfer("markdown", false, variant);
3651
+ } }) : null
3652
+ ] }) : null,
3653
+ resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_jsx_runtime25.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
3654
+ visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
3655
+ visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
3656
+ downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
3657
+ ] }) }) : null
3658
+ ] }) : null,
3659
+ prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
3660
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
3661
+ closePalette();
3662
+ void transfer(nativeAiFormat, false);
3663
+ }, children: [
3664
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "ai-copy" }),
3665
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { children: [
3666
+ "Copy with AI context",
3667
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Include source context" })
3668
+ ] })
3669
+ ] }) : null, items: quickVariants("ai"), onRun: (variant) => {
3670
+ closePalette();
3671
+ void transfer("markdown", false, variant);
3672
+ } }),
3673
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
3674
+ closePalette();
3675
+ void openWorkspace();
3676
+ }, children: [
3677
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "sliders" }),
3678
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { children: [
3679
+ "Prepare for AI",
3680
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Trim, edit or summarize" })
3681
+ ] })
3682
+ ] }) })
3683
+ ] }) : null,
3684
+ prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
3685
+ nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
3686
+ closePalette();
3687
+ void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
3688
+ }, children: [
3689
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "surface" }),
3690
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Prepare this page" })
3691
+ ] }) : null,
3692
+ variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
3693
+ closePalette();
3694
+ void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
3695
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
3696
+ ] }) }) : null,
3697
+ references.length || referenceActions.length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
3698
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { children: "References" }),
3699
+ referenceActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: [
3700
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "link" }),
3701
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: action.label }),
3702
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "m6 4 4 4-4 4" }) })
3703
+ ] }, action.id)),
3704
+ references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", title: "Copies a reference to saved data", onClick: () => void copyReference(reference), children: [
3705
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "link" }),
3706
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: reference.label })
3707
+ ] }, reference.id))
3708
+ ] }) : null,
3709
+ ["save", "chat", "email", "other"].map((group) => {
3710
+ const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
3711
+ return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
3712
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("summary", { children: [
3713
+ group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
3714
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "matrx-alchemy-disclosure-meta", children: [
3715
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: entries.length }),
3716
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "m6 4 4 4-4 4" }) })
3717
+ ] })
3718
+ ] }),
3719
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
3720
+ closePalette();
3721
+ void runAction(action);
3722
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DestinationPresentation, { action }) }, action.id)) })
3723
+ ] }, group) : null;
3724
+ })
3725
+ ] });
3726
+ const feedbackOwner = paletteTarget ?? triggerRef.current ?? feedbackDocument.current?.body ?? null;
3587
3727
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
3588
- !triggerHidden ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
3589
- setPaletteOpen(open);
3728
+ !triggerHidden && !paletteTarget ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
3590
3729
  if (open) {
3730
+ setPaletteOpen(true);
3591
3731
  setMode("copy");
3592
3732
  void preflight();
3593
- }
3733
+ } else closePalette();
3594
3734
  }, children: [
3595
3735
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { ref: triggerRef, variant: "outline", size: "icon-sm", "aria-label": `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "outline", disabled, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AlchemyGlyph, { icon }) }) : triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass", "data-alchemy-size": triggerSize, disabled }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent", "data-alchemy-size": triggerSize, disabled }) }),
3596
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
3597
- menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
3598
- table && scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "matrx-alchemy-scope", children: [
3599
- "Content scope",
3600
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
3601
- const next = scopes.find((scope) => scope === event.target.value);
3602
- if (next) {
3603
- setRequestedScope(next);
3604
- void preflight(next);
3605
- }
3606
- }, children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
3607
- ] }) : null,
3608
- copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("section", { className: "matrx-alchemy-output", children: [
3609
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
3610
- copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
3611
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
3612
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
3613
- ] }) : null,
3614
- resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
3615
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
3616
- visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
3617
- visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
3618
- ] }),
3619
- quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
3620
- closePalette();
3621
- void transfer("markdown", false, variant);
3622
- } }) : null
3623
- ] }) : null,
3624
- resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_jsx_runtime25.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
3625
- visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
3626
- visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
3627
- downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
3628
- ] }) }) : null
3629
- ] }) : null,
3630
- prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
3631
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
3632
- closePalette();
3633
- void transfer(nativeAiFormat, false);
3634
- }, children: [
3635
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "ai-copy" }),
3636
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { children: [
3637
- "Copy with AI context",
3638
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Include source context" })
3639
- ] })
3640
- ] }) : null, items: quickVariants("ai"), onRun: (variant) => {
3641
- closePalette();
3642
- void transfer("markdown", false, variant);
3643
- } }),
3644
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
3645
- closePalette();
3646
- void openWorkspace();
3647
- }, children: [
3648
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "sliders" }),
3649
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { children: [
3650
- "Prepare for AI",
3651
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Trim, edit or summarize" })
3652
- ] })
3653
- ] }) })
3654
- ] }) : null,
3655
- prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
3656
- nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
3657
- closePalette();
3658
- void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
3659
- }, children: [
3660
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "surface" }),
3661
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Prepare this page" })
3662
- ] }) : null,
3663
- variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
3664
- closePalette();
3665
- void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
3666
- }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
3667
- ] }) }) : null,
3668
- references.length || referenceActions.length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
3669
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { children: "References" }),
3670
- referenceActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: [
3671
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "link" }),
3672
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: action.label }),
3673
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "m6 4 4 4-4 4" }) })
3674
- ] }, action.id)),
3675
- references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", title: "Copies a reference to saved data", onClick: () => void copyReference(reference), children: [
3676
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaletteGlyph, { kind: "link" }),
3677
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: reference.label })
3678
- ] }, reference.id))
3679
- ] }) : null,
3680
- ["save", "chat", "email", "other"].map((group) => {
3681
- const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
3682
- return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
3683
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("summary", { children: [
3684
- group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
3685
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "matrx-alchemy-disclosure-meta", children: [
3686
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: entries.length }),
3687
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "m6 4 4 4-4 4" }) })
3688
- ] })
3689
- ] }),
3690
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
3691
- closePalette();
3692
- void runAction(action);
3693
- }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DestinationPresentation, { action }) }, action.id)) })
3694
- ] }, group) : null;
3695
- })
3696
- ] })
3736
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: palette })
3697
3737
  ] }) : null,
3698
- notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
3738
+ paletteTarget && paletteOpen ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "matrx-alchemy-menu matrx-alchemy-palette", role: "dialog", "aria-label": "Alchemy output options", children: palette }), paletteTarget) : null,
3739
+ notice && feedbackOwner ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
3699
3740
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { role: "status", children: notice }),
3700
3741
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReceiptLink, { target: receiptTarget }),
3701
3742
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
3702
- ] }), triggerRef.current.ownerDocument.body) : null,
3743
+ ] }), feedbackOwner.ownerDocument.body) : null,
3703
3744
  Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PreparationWorkspace, { restoreFocus: () => restoreFocusRef.current?.() ?? triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, scopeLabels: table?.scopeLabels, onClose: () => setWorkspaceOpen(false), onChange: (next) => setWorkspaces((current) => ({ ...current, [saved.key]: next })), transport, adapters, actions: preparedActions, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key)),
3704
3745
  emailReview
3705
3746
  ] });
@@ -5612,17 +5653,23 @@ function MatrxTableRowAlchemyProvider({ copy, placement, controls, children }) {
5612
5653
  }, 0);
5613
5654
  return () => window.clearTimeout(timer);
5614
5655
  }, [active, placement]);
5656
+ const activate = (0, import_react12.useCallback)(() => setActive(true), []);
5657
+ const mountMenu = (0, import_react12.useCallback)((target, onClose, restoreFocus) => {
5658
+ controller.current?.mountPalette(target, onClose, restoreFocus);
5659
+ }, []);
5660
+ const prepare = (0, import_react12.useCallback)(async (restoreFocus) => {
5661
+ if (copy.disabled) throw new Error("Alchemy is disabled for this record.");
5662
+ if (!controller.current) throw new Error("Alchemy is unavailable because its launcher did not mount.");
5663
+ await controller.current.preparePrimary(restoreFocus ? { restoreFocus } : void 0);
5664
+ }, [copy.disabled]);
5615
5665
  const value = {
5616
5666
  copy,
5617
5667
  controls,
5618
5668
  placement,
5619
5669
  ready: active,
5620
- activate: () => setActive(true),
5621
- prepare: async (restoreFocus) => {
5622
- if (copy.disabled) throw new Error("Alchemy is disabled for this record.");
5623
- if (!controller.current) throw new Error("Alchemy is unavailable because its launcher did not mount.");
5624
- await controller.current.preparePrimary(restoreFocus ? { restoreFocus } : void 0);
5625
- }
5670
+ activate,
5671
+ mountMenu,
5672
+ prepare
5626
5673
  };
5627
5674
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(MatrxTableRowAlchemyScope, { value, children: [
5628
5675
  active || fallback ? CopyControls ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(CopyControls, { ...copy, triggerHidden: active, controllerRef: controller }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(MatrxCopyMenu, { ...copy, triggerHidden: active, controllerRef: controller }) : null,