@shapesos/clay 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -1
- package/dist/blocks.cjs +650 -0
- package/dist/blocks.cjs.map +1 -0
- package/dist/blocks.d.cts +29 -0
- package/dist/blocks.d.ts +29 -0
- package/dist/blocks.js +21 -0
- package/dist/blocks.js.map +1 -0
- package/dist/chat.cjs +89 -47
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.d.cts +7 -3
- package/dist/chat.d.ts +7 -3
- package/dist/chat.js +3 -2
- package/dist/chunk-OKPNST44.js +1 -0
- package/dist/chunk-OKPNST44.js.map +1 -0
- package/dist/chunk-R3BGPOAM.js +230 -0
- package/dist/chunk-R3BGPOAM.js.map +1 -0
- package/dist/{chunk-TDMJUF4A.js → chunk-WPQQVKWY.js} +4 -4
- package/dist/{chunk-A77BGJH4.js → chunk-WS4IPADR.js} +34 -201
- package/dist/chunk-WS4IPADR.js.map +1 -0
- package/dist/index.cjs +129 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +27 -12
- package/dist/text-area.js +2 -2
- package/dist/types-Q9aqd9nq.d.cts +34 -0
- package/dist/types-Q9aqd9nq.d.ts +34 -0
- package/package.json +6 -1
- package/dist/chunk-A77BGJH4.js.map +0 -1
- /package/dist/{chunk-TDMJUF4A.js.map → chunk-WPQQVKWY.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/blocks/index.ts","../src/components/blocks/text-block/text-block.tsx","../src/components/blocks/block-context/block-context.tsx","../src/components/blocks/scrollable-table/scrollable-table-styles.ts","../src/tokens/colors.ts","../src/components/blocks/scrollable-table/scrollable-table.tsx","../src/components/blocks/text-block/sanitize.ts","../src/components/blocks/text-block/text-block-styles.ts","../src/tokens/typography.ts","../src/components/blocks/types.ts","../src/components/blocks/block-services/text-block-service.ts","../src/components/blocks/block-services/index.ts","../src/components/blocks/block/block.tsx"],"sourcesContent":["export { Block } from \"./block\";\nexport { BlockContext, useBlockContext } from \"./block-context\";\nexport type { BlockContextValue } from \"./block-context\";\nexport { blockTypes } from \"./types\";\nexport type { BlockRecord, BlockType, TextBlockRecord, BlockComponentProps, BlockService } from \"./types\";\nexport { BlockServices } from \"./block-services\";\nexport { TextBlockService } from \"./block-services/text-block-service\";\n","import type { ReactNode } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkGfm from \"remark-gfm\";\n\nimport { ScrollableTable, type TableCounter } from \"../scrollable-table/scrollable-table\";\nimport type { BlockComponentProps, TextBlockRecord } from \"../types\";\nimport { sanitize } from \"./sanitize\";\nimport { TextBlockWrapper } from \"./text-block-styles\";\n\n/** Renders a TEXT block as Markdown with GFM (tables, strikethrough) and line breaks. */\nexport function TextBlock({ block }: BlockComponentProps<TextBlockRecord>): ReactNode {\n const counter: TableCounter = { value: 0 };\n\n const markdownComponents = {\n table: ((tableProps: { node?: unknown; children?: ReactNode }) => (\n <ScrollableTable {...tableProps} counter={counter} />\n )) as React.ComponentType<unknown>,\n };\n\n return (\n <TextBlockWrapper>\n <ReactMarkdown remarkPlugins={[remarkGfm, remarkBreaks]} components={markdownComponents}>\n {sanitize(block.payload.text)}\n </ReactMarkdown>\n </TextBlockWrapper>\n );\n}\n","import { createContext, useContext, type ComponentType } from \"react\";\n\n/** Renderer-level concerns provided to descendants of any `Block`-rendering tree. */\nexport interface BlockContextValue {\n /** Optional component rendered next to each table in a TEXT block. Receives the zero-based table index. */\n TableActions?: ComponentType<{ tableIndex: number }>;\n}\n\nexport const BlockContext = createContext<BlockContextValue | null>(null);\n\n/** Returns the ambient block-rendering context. Returns an empty object outside a `<BlockContext.Provider>`. */\nexport function useBlockContext(): BlockContextValue {\n return useContext(BlockContext) ?? {};\n}\n","import styled from \"styled-components\";\n\nimport { colors } from \"@/tokens/colors\";\n\nexport const TableContainer = styled.div`\n position: relative;\n margin-block: 8px 16px;\n`;\n\nexport const TableScroll = styled.div`\n width: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n`;\n\nexport const TableActionsWrapper = styled.div`\n display: flex;\n justify-content: flex-start;\n margin-block: 8px 0;\n`;\n\nexport const TableActionsDivider = styled.div`\n height: 1px;\n background: ${colors[\"brown-40\"]};\n margin-block: 8px 0;\n`;\n","export const colors = {\n // White\n white: \"#FFFFFF\",\n \"white-alpha-85\": \"rgba(255, 255, 255, 0.85)\",\n \"white-alpha-40\": \"rgba(255, 255, 255, 0.40)\",\n\n // Brown\n \"brown-10\": \"#FAF9F8\",\n \"brown-20\": \"#F5F3F0\",\n \"brown-30\": \"#EEEBE5\",\n \"brown-40\": \"#E6E2DA\",\n \"brown-50\": \"#CFCBC4\",\n \"brown-60\": \"#A19E99\",\n \"brown-70\": \"#73716D\",\n \"brown-80\": \"#5C5A57\",\n \"brown-90\": \"#2E2D2C\",\n \"brown-100\": \"#171716\",\n \"brown-alpha-12\": \"rgba(23, 23, 22, 0.12)\",\n \"brown-alpha-20\": \"rgba(23, 23, 22, 0.20)\",\n \"brown-alpha-55\": \"rgba(23, 23, 22, 0.55)\",\n \"brown-alpha-70\": \"rgba(23, 23, 22, 0.70)\",\n \"brown-alpha-80\": \"rgba(23, 23, 22, 0.80)\",\n \"brown-alpha-90\": \"rgba(23, 23, 22, 0.90)\",\n\n // Fuchsia\n \"fuchsia-50\": \"#FAF5FF\",\n \"fuchsia-300\": \"#F0ABFC\",\n \"fuchsia-500\": \"#D946EF\",\n \"fuchsia-600\": \"#C026D3\",\n \"fuchsia-800\": \"#86198F\",\n\n // Pink\n \"pink-50\": \"#FDF2F8\",\n \"pink-400\": \"#F472B6\",\n \"pink-600\": \"#DB2777\",\n \"pink-800\": \"#9D174D\",\n\n // Violet\n \"violet-50\": \"#F5F3FF\",\n \"violet-400\": \"#A78BFA\",\n \"violet-600\": \"#7C3AED\",\n \"violet-800\": \"#5B21B6\",\n\n // Indigo\n \"indigo-50\": \"#EEF2FF\",\n \"indigo-400\": \"#818CF8\",\n \"indigo-500\": \"#6366F1\",\n \"indigo-600\": \"#4F46E5\",\n \"indigo-800\": \"#3730A3\",\n\n // Cyan\n \"cyan-50\": \"#E7FEFF\",\n \"cyan-300\": \"#67E8F9\",\n \"cyan-600\": \"#0891B2\",\n \"cyan-900\": \"#164E63\",\n\n // Teal\n \"teal-50\": \"#EBFDF9\",\n \"teal-300\": \"#5EEAD4\",\n \"teal-600\": \"#0D9488\",\n\n // Rose\n \"rose-400\": \"#FB7185\",\n\n // Purple\n \"purple-400\": \"#C084FC\",\n\n // Blue\n \"blue-50\": \"#EFF6FF\",\n \"blue-100\": \"#DBEAFE\",\n \"blue-300\": \"#93C5FD\",\n \"blue-400\": \"#60A5FA\",\n \"blue-600\": \"#2563EB\",\n \"blue-800\": \"#1E40AF\",\n\n // Sky\n \"sky-300\": \"#7DD3FC\",\n\n // Green\n \"green-50\": \"#ECF9F0\",\n \"green-100\": \"#D4F1D9\",\n \"green-400\": \"#3DC269\",\n \"green-700\": \"#277C43\",\n \"green-800\": \"#1C5930\",\n\n // Orange\n \"orange-50\": \"#FFF7ED\",\n \"orange-100\": \"#FFEDD5\",\n \"orange-200\": \"#FED7AA\",\n \"orange-500\": \"#F97316\",\n \"orange-600\": \"#EA580C\",\n\n // Red\n \"red-50\": \"#FEF2F2\",\n \"red-100\": \"#FEE2E2\",\n \"red-200\": \"#FECACA\",\n \"red-400\": \"#F7776C\",\n \"red-500\": \"#EF4444\",\n \"red-600\": \"#DC2626\",\n} as const;\n\nexport type ColorToken = keyof typeof colors;\n","import { type ReactNode } from \"react\";\n\nimport { useBlockContext } from \"../block-context/block-context\";\nimport { TableActionsWrapper, TableActionsDivider, TableContainer, TableScroll } from \"./scrollable-table-styles\";\n\n/** Mutable counter used to assign sequential table indices during a single render pass. */\nexport interface TableCounter {\n /** The current value; incremented each time a table component is rendered. */\n value: number;\n}\n\n/** Props for the ScrollableTable component. */\ninterface ScrollableTableProps {\n /** Unused node prop from react-markdown. */\n node?: unknown;\n /** Table children elements. */\n children?: ReactNode;\n /** Mutable counter for tracking table indices. */\n counter?: TableCounter;\n}\n\n/** Renders a table inside a horizontally scrollable wrapper with optional actions below. */\nexport function ScrollableTable({ node: _node, counter, ...props }: ScrollableTableProps): ReactNode {\n const currentIndex = counter ? counter.value : 0;\n if (counter) {\n // eslint-disable-next-line react-hooks/immutability -- Counter is an intentionally mutable shared object for sequential table indexing\n counter.value += 1;\n }\n\n const { TableActions } = useBlockContext();\n\n return (\n <TableContainer>\n <TableScroll>\n <table {...props} />\n </TableScroll>\n {TableActions && (\n <>\n <TableActionsWrapper>\n <TableActions tableIndex={currentIndex} />\n </TableActionsWrapper>\n <TableActionsDivider />\n </>\n )}\n </TableContainer>\n );\n}\n","// Strips io-server's `<!-- table-title: ... -->` HTML-comment metadata before rendering.\n// The marker is emitted by the server's CSV-export pipeline so the export button can label\n// the file; it has no place in the visual output. If the server-side format changes\n// (prefix, spacing, closing-tag style), this filter silently stops matching and the\n// raw HTML comment leaks into rendered Markdown — keep this contract aligned with io-server.\nexport function sanitize(text: string): string {\n return text\n .split(\"\\n\")\n .filter((line) => {\n const t = line.trim();\n return !(t.startsWith(\"<!-- table-title:\") && t.endsWith(\"-->\"));\n })\n .join(\"\\n\");\n}\n","import styled from \"styled-components\";\n\nimport { colors } from \"@/tokens/colors\";\nimport { typographyMixin, typographyTypes } from \"@/tokens/typography\";\n\nexport const TextBlockWrapper = styled.div`\n ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};\n color: ${colors[\"brown-100\"]};\n word-break: break-word;\n\n & h1 {\n ${typographyMixin(typographyTypes.GEIST_HEADING_S_BOLD)};\n margin-block: 20px;\n }\n\n & h2 {\n ${typographyMixin(typographyTypes.GEIST_BODY_L_SEMI_BOLD)};\n margin-block: 12px;\n }\n\n & h3,\n & h4,\n & h5,\n & h6 {\n ${typographyMixin(typographyTypes.GEIST_BODY_M_SEMI_BOLD)};\n margin-block: 8px;\n }\n\n & strong {\n ${typographyMixin(typographyTypes.GEIST_BODY_S_SEMI_BOLD)};\n }\n\n & p {\n margin-block: 0px;\n }\n\n & p + p {\n margin-block: 8px 0px;\n }\n\n & ul,\n & ol {\n margin-block: 16px;\n padding-left: 20px;\n }\n\n & li + li {\n margin-block: 4px;\n }\n\n & ol {\n list-style-type: decimal;\n }\n\n & ol ol {\n list-style-type: lower-alpha;\n }\n\n & ol ol ol {\n list-style-type: lower-roman;\n }\n\n & a {\n color: inherit;\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: auto;\n text-underline-offset: auto;\n text-underline-position: from-font;\n transition: color 75ms ease-in-out;\n\n &:hover {\n color: ${colors[\"blue-600\"]};\n }\n }\n\n & hr {\n border: none;\n border-top: 1px solid ${colors[\"brown-40\"]};\n margin-block: 20px;\n }\n\n & table {\n margin: 0;\n width: 100%;\n border-collapse: collapse;\n }\n\n & th,\n & td {\n border: none;\n border-bottom: 1px solid ${colors[\"brown-40\"]};\n text-align: left;\n }\n\n & th {\n ${typographyMixin(typographyTypes.GEIST_LABEL_CAPTION_MEDIUM)};\n padding: 8px;\n }\n\n & td {\n ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};\n padding: 16px 8px;\n min-width: 150px;\n width: 1%;\n }\n\n & td strong {\n font-weight: inherit;\n font-size: inherit;\n line-height: inherit;\n }\n\n & blockquote {\n margin-block: 4px;\n margin-inline: 0px;\n padding-left: 16px;\n border-left: 4px solid ${colors[\"brown-40\"]};\n color: ${colors[\"brown-80\"]};\n }\n`;\n","/** Available font families in the Shapes.co design system. */\nexport const fontFamilies = {\n /** Geist — primary UI font for body text, labels, headings, and display. */\n GEIST: \"Geist\",\n /** Crimson Pro — editorial/serif font, always italic. Used for decorative headings and pull quotes. */\n CRIMSON_PRO: \"Crimson Pro\",\n} as const;\n\nexport const typographyTypes = {\n // Geist Label Caption (12px)\n GEIST_LABEL_CAPTION_REGULAR: \"GEIST_LABEL_CAPTION_REGULAR\",\n GEIST_LABEL_CAPTION_MEDIUM: \"GEIST_LABEL_CAPTION_MEDIUM\",\n GEIST_LABEL_CAPTION_SEMI_BOLD: \"GEIST_LABEL_CAPTION_SEMI_BOLD\",\n\n // Geist Body Extra Small (14px)\n GEIST_BODY_XS_REGULAR: \"GEIST_BODY_XS_REGULAR\",\n GEIST_BODY_XS_MEDIUM: \"GEIST_BODY_XS_MEDIUM\",\n GEIST_BODY_XS_BOLD: \"GEIST_BODY_XS_BOLD\",\n\n // Geist Body Small (16px)\n GEIST_BODY_S_REGULAR: \"GEIST_BODY_S_REGULAR\",\n GEIST_BODY_S_MEDIUM: \"GEIST_BODY_S_MEDIUM\",\n GEIST_BODY_S_SEMI_BOLD: \"GEIST_BODY_S_SEMI_BOLD\",\n GEIST_BODY_S_BOLD: \"GEIST_BODY_S_BOLD\",\n\n // Geist Body Medium (18px)\n GEIST_BODY_M_LIGHT: \"GEIST_BODY_M_LIGHT\",\n GEIST_BODY_M_REGULAR: \"GEIST_BODY_M_REGULAR\",\n GEIST_BODY_M_MEDIUM: \"GEIST_BODY_M_MEDIUM\",\n GEIST_BODY_M_SEMI_BOLD: \"GEIST_BODY_M_SEMI_BOLD\",\n\n // Geist Body Large (20px)\n GEIST_BODY_L_REGULAR: \"GEIST_BODY_L_REGULAR\",\n GEIST_BODY_L_MEDIUM: \"GEIST_BODY_L_MEDIUM\",\n GEIST_BODY_L_SEMI_BOLD: \"GEIST_BODY_L_SEMI_BOLD\",\n GEIST_BODY_L_BOLD: \"GEIST_BODY_L_BOLD\",\n\n // Geist Heading Small (24px)\n GEIST_HEADING_S_REGULAR: \"GEIST_HEADING_S_REGULAR\",\n GEIST_HEADING_S_MEDIUM: \"GEIST_HEADING_S_MEDIUM\",\n GEIST_HEADING_S_BOLD: \"GEIST_HEADING_S_BOLD\",\n\n // Geist Heading Medium (28px)\n GEIST_HEADING_M_BOLD: \"GEIST_HEADING_M_BOLD\",\n\n // Geist Heading Large (32px)\n GEIST_HEADING_L_REGULAR: \"GEIST_HEADING_L_REGULAR\",\n GEIST_HEADING_L_MEDIUM: \"GEIST_HEADING_L_MEDIUM\",\n GEIST_HEADING_L_SEMI_BOLD: \"GEIST_HEADING_L_SEMI_BOLD\",\n GEIST_HEADING_L_BOLD: \"GEIST_HEADING_L_BOLD\",\n\n // Geist Display Large (36px)\n GEIST_DISPLAY_L_MEDIUM: \"GEIST_DISPLAY_L_MEDIUM\",\n\n // Crimson Pro Body Small (16px)\n CRIMSON_PRO_BODY_S_LIGHT: \"CRIMSON_PRO_BODY_S_LIGHT\",\n\n // Crimson Pro Body Medium (18px)\n CRIMSON_PRO_BODY_M_LIGHT: \"CRIMSON_PRO_BODY_M_LIGHT\",\n\n // Crimson Pro Heading Medium (24px)\n CRIMSON_PRO_HEADING_M_MEDIUM: \"CRIMSON_PRO_HEADING_M_MEDIUM\",\n\n // Crimson Pro Display Extra Large (46px)\n CRIMSON_PRO_DISPLAY_XL_REGULAR: \"CRIMSON_PRO_DISPLAY_XL_REGULAR\",\n} as const;\n\n/** Union of all typography type string constants. Used as keys into `typographyStyles`. */\nexport type TypographyType = (typeof typographyTypes)[keyof typeof typographyTypes];\n\n/** CSS properties for a single typography type. All numeric values are in pixels. */\nexport interface TypographyStyle {\n /** Font family name (e.g., \"Geist\"). */\n fontFamily: string;\n /** Font size in pixels. */\n fontSize: number;\n /** Font weight (100–900). */\n fontWeight: number;\n /** Line height in pixels. */\n lineHeight: number;\n /** Letter spacing in pixels. Omitted when the font's default spacing is correct. */\n letterSpacing?: number;\n /** CSS font-style value (e.g., \"italic\"). Omitted for normal style. */\n fontStyle?: string;\n}\n\nexport const typographyStyles: Record<TypographyType, TypographyStyle> = {\n // Geist Label Caption (12px)\n [typographyTypes.GEIST_LABEL_CAPTION_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 400,\n lineHeight: 16,\n },\n [typographyTypes.GEIST_LABEL_CAPTION_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 500,\n lineHeight: 16,\n },\n [typographyTypes.GEIST_LABEL_CAPTION_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 12,\n fontWeight: 600,\n lineHeight: 16,\n },\n\n // Geist Body Extra Small (14px)\n [typographyTypes.GEIST_BODY_XS_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 400,\n lineHeight: 20,\n },\n [typographyTypes.GEIST_BODY_XS_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 500,\n lineHeight: 20,\n },\n [typographyTypes.GEIST_BODY_XS_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 14,\n fontWeight: 600,\n lineHeight: 20,\n },\n\n // Geist Body Small (16px)\n [typographyTypes.GEIST_BODY_S_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 400,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 500,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 600,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n [typographyTypes.GEIST_BODY_S_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 16,\n fontWeight: 700,\n lineHeight: 24,\n letterSpacing: -0.08,\n },\n\n // Geist Body Medium (18px)\n [typographyTypes.GEIST_BODY_M_LIGHT]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 300,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 400,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 500,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n [typographyTypes.GEIST_BODY_M_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 18,\n fontWeight: 600,\n lineHeight: 28,\n letterSpacing: -0.09,\n },\n\n // Geist Body Large (20px)\n [typographyTypes.GEIST_BODY_L_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 400,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 500,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 600,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n [typographyTypes.GEIST_BODY_L_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 20,\n fontWeight: 700,\n lineHeight: 30,\n letterSpacing: -0.2,\n },\n\n // Geist Heading Small (24px)\n [typographyTypes.GEIST_HEADING_S_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 400,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n [typographyTypes.GEIST_HEADING_S_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 500,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n [typographyTypes.GEIST_HEADING_S_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 24,\n fontWeight: 700,\n lineHeight: 32,\n letterSpacing: -0.48,\n },\n\n // Geist Heading Medium (28px)\n [typographyTypes.GEIST_HEADING_M_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 28,\n fontWeight: 700,\n lineHeight: 36,\n letterSpacing: -0.6,\n },\n\n // Geist Heading Large (32px)\n [typographyTypes.GEIST_HEADING_L_REGULAR]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 400,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 500,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_SEMI_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 600,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n [typographyTypes.GEIST_HEADING_L_BOLD]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 32,\n fontWeight: 700,\n lineHeight: 40,\n letterSpacing: -0.64,\n },\n\n // Geist Display Large (36px)\n [typographyTypes.GEIST_DISPLAY_L_MEDIUM]: {\n fontFamily: fontFamilies.GEIST,\n fontSize: 36,\n fontWeight: 500,\n lineHeight: 44,\n letterSpacing: -0.72,\n },\n\n // Crimson Pro Body Small (16px)\n [typographyTypes.CRIMSON_PRO_BODY_S_LIGHT]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 16,\n fontWeight: 300,\n lineHeight: 20,\n letterSpacing: -0.32,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Body Medium (18px)\n [typographyTypes.CRIMSON_PRO_BODY_M_LIGHT]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 18,\n fontWeight: 300,\n lineHeight: 28,\n letterSpacing: 0,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Heading Medium (24px)\n [typographyTypes.CRIMSON_PRO_HEADING_M_MEDIUM]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 24,\n fontWeight: 400,\n lineHeight: 32,\n letterSpacing: -0.48,\n fontStyle: \"italic\",\n },\n\n // Crimson Pro Display Extra Large (46px)\n [typographyTypes.CRIMSON_PRO_DISPLAY_XL_REGULAR]: {\n fontFamily: fontFamilies.CRIMSON_PRO,\n fontSize: 46,\n fontWeight: 400,\n lineHeight: 54,\n letterSpacing: -1.38,\n fontStyle: \"italic\",\n },\n};\n\n/**\n * Generates a CSS string for a given typography type, suitable for use in styled-components template literals.\n * @param type - The typography type constant (e.g., `typographyTypes.GEIST_BODY_S_REGULAR`).\n * @returns A semicolon-separated CSS string with font-family, font-size, font-weight, line-height, letter-spacing, and font-style.\n */\nexport function typographyMixin(type: TypographyType): string {\n const style = typographyStyles[type];\n return [\n `font-family: \"${style.fontFamily}\", sans-serif`,\n `font-size: ${style.fontSize}px`,\n `font-weight: ${style.fontWeight}`,\n `line-height: ${style.lineHeight}px`,\n `letter-spacing: ${style.letterSpacing != null ? `${style.letterSpacing}px` : \"inherit\"}`,\n `font-style: ${style.fontStyle ?? \"normal\"}`,\n ].join(\";\\n \");\n}\n","import type { ComponentType } from \"react\";\n\n/** Block-type discriminator constants. Mirrors the wire shape from io-server / shapes-agent. */\nexport const blockTypes = {\n TEXT: \"TEXT\",\n} as const;\n\n/** Discriminator for content blocks. */\nexport type BlockType = (typeof blockTypes)[keyof typeof blockTypes];\n\n/** Plain-text content block — rendered as Markdown. */\nexport interface TextBlockRecord {\n /** Block-type discriminator. */\n type: typeof blockTypes.TEXT;\n /** Type-specific data; kept as `payload` to match the wire shape 1:1. */\n payload: {\n /** The Markdown source for this text segment. */\n text: string;\n };\n}\n\n/** Discriminated union of all supported content blocks. Additive — new types extend this union. */\nexport type BlockRecord = TextBlockRecord;\n\n/** Props every concrete block component receives from the dispatcher. */\nexport interface BlockComponentProps<TBlock extends BlockRecord = BlockRecord> {\n /** The block to render. */\n block: TBlock;\n}\n\n/** Per-block-type service — registry entry that pairs a discriminator with its concrete renderer. */\nexport interface BlockService<TBlock extends BlockRecord = BlockRecord> {\n /** Discriminator value this service handles. */\n type: BlockType;\n /** React component that renders a block of this type. */\n Component: ComponentType<BlockComponentProps<TBlock>>;\n}\n","import { TextBlock } from \"../text-block/text-block\";\nimport { blockTypes } from \"../types\";\nimport type { BlockService, TextBlockRecord } from \"../types\";\n\nexport const TextBlockService: BlockService<TextBlockRecord> = {\n type: blockTypes.TEXT,\n Component: TextBlock,\n};\n","import type { BlockService, BlockType } from \"../types\";\nimport { TextBlockService } from \"./text-block-service\";\n\nexport const BlockServices: Record<BlockType, BlockService> = {\n [TextBlockService.type]: TextBlockService,\n};\n","import type { ReactNode } from \"react\";\n\nimport { BlockServices } from \"../block-services\";\nimport type { BlockRecord } from \"../types\";\n\n/** Props for the Block dispatcher. */\ninterface BlockProps {\n /** The block to render. Dispatched to the registered concrete component for its `type`. */\n block: BlockRecord;\n}\n\n/** Dispatches a single block to its registered concrete component. Unknown types render as a no-op. */\nexport function Block({ block }: BlockProps): ReactNode {\n const service = BlockServices[block.type];\n if (!service) return null;\n const { Component } = service;\n return <Component block={block} />;\n}\n"],"mappings":"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","names":["styled","import_styled_components","styled","import_jsx_runtime","ReactMarkdown","remarkGfm","remarkBreaks","import_jsx_runtime"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ComponentType } from 'react';
|
|
3
|
+
import { a as BlockRecord, c as BlockType, b as BlockService, T as TextBlockRecord } from './types-Q9aqd9nq.cjs';
|
|
4
|
+
export { B as BlockComponentProps, d as blockTypes } from './types-Q9aqd9nq.cjs';
|
|
5
|
+
|
|
6
|
+
/** Props for the Block dispatcher. */
|
|
7
|
+
interface BlockProps {
|
|
8
|
+
/** The block to render. Dispatched to the registered concrete component for its `type`. */
|
|
9
|
+
block: BlockRecord;
|
|
10
|
+
}
|
|
11
|
+
/** Dispatches a single block to its registered concrete component. Unknown types render as a no-op. */
|
|
12
|
+
declare function Block({ block }: BlockProps): ReactNode;
|
|
13
|
+
|
|
14
|
+
/** Renderer-level concerns provided to descendants of any `Block`-rendering tree. */
|
|
15
|
+
interface BlockContextValue {
|
|
16
|
+
/** Optional component rendered next to each table in a TEXT block. Receives the zero-based table index. */
|
|
17
|
+
TableActions?: ComponentType<{
|
|
18
|
+
tableIndex: number;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
declare const BlockContext: react.Context<BlockContextValue | null>;
|
|
22
|
+
/** Returns the ambient block-rendering context. Returns an empty object outside a `<BlockContext.Provider>`. */
|
|
23
|
+
declare function useBlockContext(): BlockContextValue;
|
|
24
|
+
|
|
25
|
+
declare const BlockServices: Record<BlockType, BlockService>;
|
|
26
|
+
|
|
27
|
+
declare const TextBlockService: BlockService<TextBlockRecord>;
|
|
28
|
+
|
|
29
|
+
export { Block, BlockContext, type BlockContextValue, BlockRecord, BlockService, BlockServices, BlockType, TextBlockRecord, TextBlockService, useBlockContext };
|
package/dist/blocks.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ComponentType } from 'react';
|
|
3
|
+
import { a as BlockRecord, c as BlockType, b as BlockService, T as TextBlockRecord } from './types-Q9aqd9nq.js';
|
|
4
|
+
export { B as BlockComponentProps, d as blockTypes } from './types-Q9aqd9nq.js';
|
|
5
|
+
|
|
6
|
+
/** Props for the Block dispatcher. */
|
|
7
|
+
interface BlockProps {
|
|
8
|
+
/** The block to render. Dispatched to the registered concrete component for its `type`. */
|
|
9
|
+
block: BlockRecord;
|
|
10
|
+
}
|
|
11
|
+
/** Dispatches a single block to its registered concrete component. Unknown types render as a no-op. */
|
|
12
|
+
declare function Block({ block }: BlockProps): ReactNode;
|
|
13
|
+
|
|
14
|
+
/** Renderer-level concerns provided to descendants of any `Block`-rendering tree. */
|
|
15
|
+
interface BlockContextValue {
|
|
16
|
+
/** Optional component rendered next to each table in a TEXT block. Receives the zero-based table index. */
|
|
17
|
+
TableActions?: ComponentType<{
|
|
18
|
+
tableIndex: number;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
declare const BlockContext: react.Context<BlockContextValue | null>;
|
|
22
|
+
/** Returns the ambient block-rendering context. Returns an empty object outside a `<BlockContext.Provider>`. */
|
|
23
|
+
declare function useBlockContext(): BlockContextValue;
|
|
24
|
+
|
|
25
|
+
declare const BlockServices: Record<BlockType, BlockService>;
|
|
26
|
+
|
|
27
|
+
declare const TextBlockService: BlockService<TextBlockRecord>;
|
|
28
|
+
|
|
29
|
+
export { Block, BlockContext, type BlockContextValue, BlockRecord, BlockService, BlockServices, BlockType, TextBlockRecord, TextBlockService, useBlockContext };
|
package/dist/blocks.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "./chunk-OKPNST44.js";
|
|
2
|
+
import {
|
|
3
|
+
Block,
|
|
4
|
+
BlockContext,
|
|
5
|
+
BlockServices,
|
|
6
|
+
TextBlockService,
|
|
7
|
+
blockTypes,
|
|
8
|
+
useBlockContext
|
|
9
|
+
} from "./chunk-R3BGPOAM.js";
|
|
10
|
+
import "./chunk-SV24ONND.js";
|
|
11
|
+
import "./chunk-JF3P66JF.js";
|
|
12
|
+
import "./chunk-5WRI5ZAA.js";
|
|
13
|
+
export {
|
|
14
|
+
Block,
|
|
15
|
+
BlockContext,
|
|
16
|
+
BlockServices,
|
|
17
|
+
TextBlockService,
|
|
18
|
+
blockTypes,
|
|
19
|
+
useBlockContext
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/chat.cjs
CHANGED
|
@@ -38,26 +38,22 @@ __export(chat_exports, {
|
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(chat_exports);
|
|
40
40
|
|
|
41
|
-
// src/components/chat/chat-message
|
|
41
|
+
// src/components/chat/chat-message/chat-message.tsx
|
|
42
|
+
var import_react7 = require("react");
|
|
43
|
+
|
|
44
|
+
// src/components/blocks/text-block/text-block.tsx
|
|
42
45
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
43
46
|
var import_remark_breaks = __toESM(require("remark-breaks"), 1);
|
|
44
47
|
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
45
48
|
|
|
46
|
-
// src/components/
|
|
47
|
-
var import_react2 = require("react");
|
|
48
|
-
|
|
49
|
-
// src/components/chat/chat-context/chat-context.ts
|
|
49
|
+
// src/components/blocks/block-context/block-context.tsx
|
|
50
50
|
var import_react = require("react");
|
|
51
|
-
var
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
if (!context) {
|
|
55
|
-
throw new Error("useChatContext must be used within a Chat.Root component");
|
|
56
|
-
}
|
|
57
|
-
return context;
|
|
51
|
+
var BlockContext = (0, import_react.createContext)(null);
|
|
52
|
+
function useBlockContext() {
|
|
53
|
+
return (0, import_react.useContext)(BlockContext) ?? {};
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
// src/components/
|
|
56
|
+
// src/components/blocks/scrollable-table/scrollable-table-styles.ts
|
|
61
57
|
var import_styled_components = __toESM(require("styled-components"), 1);
|
|
62
58
|
|
|
63
59
|
// src/tokens/colors.ts
|
|
@@ -148,7 +144,7 @@ var colors = {
|
|
|
148
144
|
"red-600": "#DC2626"
|
|
149
145
|
};
|
|
150
146
|
|
|
151
|
-
// src/components/
|
|
147
|
+
// src/components/blocks/scrollable-table/scrollable-table-styles.ts
|
|
152
148
|
var TableContainer = import_styled_components.default.div`
|
|
153
149
|
position: relative;
|
|
154
150
|
margin-block: 8px 16px;
|
|
@@ -169,25 +165,32 @@ var TableActionsDivider = import_styled_components.default.div`
|
|
|
169
165
|
margin-block: 8px 0;
|
|
170
166
|
`;
|
|
171
167
|
|
|
172
|
-
// src/components/
|
|
168
|
+
// src/components/blocks/scrollable-table/scrollable-table.tsx
|
|
173
169
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
174
|
-
function ScrollableTable({ node: _node,
|
|
170
|
+
function ScrollableTable({ node: _node, counter, ...props }) {
|
|
175
171
|
const currentIndex = counter ? counter.value : 0;
|
|
176
172
|
if (counter) {
|
|
177
173
|
counter.value += 1;
|
|
178
174
|
}
|
|
179
|
-
const
|
|
180
|
-
const TableActions = context?.TableActions;
|
|
175
|
+
const { TableActions } = useBlockContext();
|
|
181
176
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableContainer, { children: [
|
|
182
177
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) }),
|
|
183
|
-
TableActions &&
|
|
184
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActionsWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActions, {
|
|
178
|
+
TableActions && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
179
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActionsWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActions, { tableIndex: currentIndex }) }),
|
|
185
180
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActionsDivider, {})
|
|
186
181
|
] })
|
|
187
182
|
] });
|
|
188
183
|
}
|
|
189
184
|
|
|
190
|
-
// src/components/
|
|
185
|
+
// src/components/blocks/text-block/sanitize.ts
|
|
186
|
+
function sanitize(text) {
|
|
187
|
+
return text.split("\n").filter((line) => {
|
|
188
|
+
const t = line.trim();
|
|
189
|
+
return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
|
|
190
|
+
}).join("\n");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// src/components/blocks/text-block/text-block-styles.ts
|
|
191
194
|
var import_styled_components2 = __toESM(require("styled-components"), 1);
|
|
192
195
|
|
|
193
196
|
// src/tokens/typography.ts
|
|
@@ -485,8 +488,8 @@ function typographyMixin(type) {
|
|
|
485
488
|
].join(";\n ");
|
|
486
489
|
}
|
|
487
490
|
|
|
488
|
-
// src/components/
|
|
489
|
-
var
|
|
491
|
+
// src/components/blocks/text-block/text-block-styles.ts
|
|
492
|
+
var TextBlockWrapper = import_styled_components2.default.div`
|
|
490
493
|
${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
|
|
491
494
|
color: ${colors["brown-100"]};
|
|
492
495
|
word-break: break-word;
|
|
@@ -603,18 +606,50 @@ var ContentWrapper = import_styled_components2.default.div`
|
|
|
603
606
|
}
|
|
604
607
|
`;
|
|
605
608
|
|
|
606
|
-
// src/components/
|
|
609
|
+
// src/components/blocks/text-block/text-block.tsx
|
|
607
610
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
608
|
-
function
|
|
611
|
+
function TextBlock({ block }) {
|
|
609
612
|
const counter = { value: 0 };
|
|
610
|
-
const sanitizedContent = content.split("\n").filter((line) => {
|
|
611
|
-
const t = line.trim();
|
|
612
|
-
return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
|
|
613
|
-
}).join("\n");
|
|
614
613
|
const markdownComponents = {
|
|
615
|
-
table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ScrollableTable, { ...tableProps,
|
|
614
|
+
table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ScrollableTable, { ...tableProps, counter }))
|
|
616
615
|
};
|
|
617
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: markdownComponents, children: sanitize(block.payload.text) }) });
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// src/components/blocks/types.ts
|
|
620
|
+
var blockTypes = {
|
|
621
|
+
TEXT: "TEXT"
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
// src/components/blocks/block-services/text-block-service.ts
|
|
625
|
+
var TextBlockService = {
|
|
626
|
+
type: blockTypes.TEXT,
|
|
627
|
+
Component: TextBlock
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// src/components/blocks/block-services/index.ts
|
|
631
|
+
var BlockServices = {
|
|
632
|
+
[TextBlockService.type]: TextBlockService
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
// src/components/blocks/block/block.tsx
|
|
636
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
637
|
+
function Block({ block }) {
|
|
638
|
+
const service = BlockServices[block.type];
|
|
639
|
+
if (!service) return null;
|
|
640
|
+
const { Component } = service;
|
|
641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Component, { block });
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// src/components/chat/chat-context/chat-context.ts
|
|
645
|
+
var import_react2 = require("react");
|
|
646
|
+
var ChatContext = (0, import_react2.createContext)(null);
|
|
647
|
+
function useChatContext() {
|
|
648
|
+
const context = (0, import_react2.useContext)(ChatContext);
|
|
649
|
+
if (!context) {
|
|
650
|
+
throw new Error("useChatContext must be used within a Chat.Root component");
|
|
651
|
+
}
|
|
652
|
+
return context;
|
|
618
653
|
}
|
|
619
654
|
|
|
620
655
|
// src/components/chat/chat-message-actions/chat-message-actions.tsx
|
|
@@ -718,10 +753,10 @@ var IconWrapper = import_styled_components3.default.span`
|
|
|
718
753
|
`;
|
|
719
754
|
|
|
720
755
|
// src/components/icon/icon.tsx
|
|
721
|
-
var
|
|
756
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
722
757
|
var DEFAULT_SIZE = 16;
|
|
723
758
|
var Icon = (0, import_react4.forwardRef)(function Icon2({ icon: IconComponent, size = DEFAULT_SIZE, color, className, "aria-label": ariaLabel }, ref) {
|
|
724
|
-
return /* @__PURE__ */ (0,
|
|
759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
725
760
|
IconWrapper,
|
|
726
761
|
{
|
|
727
762
|
ref,
|
|
@@ -729,7 +764,7 @@ var Icon = (0, import_react4.forwardRef)(function Icon2({ icon: IconComponent, s
|
|
|
729
764
|
$color: color,
|
|
730
765
|
"aria-label": ariaLabel,
|
|
731
766
|
role: ariaLabel ? "img" : void 0,
|
|
732
|
-
children: /* @__PURE__ */ (0,
|
|
767
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconComponent, { width: size, height: size, strokeWidth: getStrokeWidth(size) })
|
|
733
768
|
}
|
|
734
769
|
);
|
|
735
770
|
});
|
|
@@ -778,7 +813,7 @@ var Button = import_styled_components4.default.button`
|
|
|
778
813
|
`;
|
|
779
814
|
|
|
780
815
|
// src/components/icon-button/icon-button.tsx
|
|
781
|
-
var
|
|
816
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
782
817
|
var ICON_SIZE_BY_BUTTON_SIZE = {
|
|
783
818
|
small: 16,
|
|
784
819
|
medium: 20
|
|
@@ -795,7 +830,7 @@ function IconButton({
|
|
|
795
830
|
as,
|
|
796
831
|
"aria-label": ariaLabel
|
|
797
832
|
}) {
|
|
798
|
-
return /* @__PURE__ */ (0,
|
|
833
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
799
834
|
Button,
|
|
800
835
|
{
|
|
801
836
|
className,
|
|
@@ -807,7 +842,7 @@ function IconButton({
|
|
|
807
842
|
disabled,
|
|
808
843
|
onClick: disabled ? void 0 : onClick,
|
|
809
844
|
"aria-label": ariaLabel,
|
|
810
|
-
children: /* @__PURE__ */ (0,
|
|
845
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
|
|
811
846
|
}
|
|
812
847
|
);
|
|
813
848
|
}
|
|
@@ -892,7 +927,7 @@ var AnimatedAction = import_styled_components5.default.div`
|
|
|
892
927
|
`;
|
|
893
928
|
|
|
894
929
|
// src/components/chat/chat-message-actions/chat-message-actions.tsx
|
|
895
|
-
var
|
|
930
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
896
931
|
function ChatMessageActions({ className, messageId, content, role, isHelpful }) {
|
|
897
932
|
const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
|
|
898
933
|
const { isCopied, copy } = useCopyToClipboard();
|
|
@@ -908,8 +943,8 @@ function ChatMessageActions({ className, messageId, content, role, isHelpful })
|
|
|
908
943
|
}, [messageId, isHelpful, onThumbDownClick]);
|
|
909
944
|
const isAssistant = role === MESSAGE_ROLE.ASSISTANT;
|
|
910
945
|
const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
|
|
911
|
-
return /* @__PURE__ */ (0,
|
|
912
|
-
/* @__PURE__ */ (0,
|
|
946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(ActionsContainer, { $role: role, className, children: [
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
913
948
|
IconButton,
|
|
914
949
|
{
|
|
915
950
|
icon: isCopied ? IconCheck : IconCopy,
|
|
@@ -917,7 +952,7 @@ function ChatMessageActions({ className, messageId, content, role, isHelpful })
|
|
|
917
952
|
"aria-label": isCopied ? "Copied" : "Copy message"
|
|
918
953
|
}
|
|
919
954
|
),
|
|
920
|
-
hasFeedback && /* @__PURE__ */ (0,
|
|
955
|
+
hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
921
956
|
IconButton,
|
|
922
957
|
{
|
|
923
958
|
icon: IconThumbUp,
|
|
@@ -926,7 +961,7 @@ function ChatMessageActions({ className, messageId, content, role, isHelpful })
|
|
|
926
961
|
"aria-label": "Good response"
|
|
927
962
|
}
|
|
928
963
|
) }),
|
|
929
|
-
hasFeedback && /* @__PURE__ */ (0,
|
|
964
|
+
hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
930
965
|
IconButton,
|
|
931
966
|
{
|
|
932
967
|
icon: IconThumbDown,
|
|
@@ -968,15 +1003,22 @@ var MessageBubble = import_styled_components6.default.div`
|
|
|
968
1003
|
`;
|
|
969
1004
|
|
|
970
1005
|
// src/components/chat/chat-message/chat-message.tsx
|
|
971
|
-
var
|
|
1006
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
972
1007
|
function ChatMessage({ message }) {
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1008
|
+
const { TableActions: ChatTableActions } = useChatContext();
|
|
1009
|
+
const blockContextValue = (0, import_react7.useMemo)(
|
|
1010
|
+
() => ({
|
|
1011
|
+
TableActions: ChatTableActions ? ({ tableIndex }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChatTableActions, { messageId: message.id, tableIndex }) : void 0
|
|
1012
|
+
}),
|
|
1013
|
+
[ChatTableActions, message.id]
|
|
1014
|
+
);
|
|
1015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageRow, { $role: message.role, role: "article", "aria-label": `${message.role} message`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageContainer, { $role: message.role, children: [
|
|
1016
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BlockContext.Provider, { value: blockContextValue, children: message.blocks.map((block, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Block, { block }, index)) }) }),
|
|
1017
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
976
1018
|
ChatMessageActions,
|
|
977
1019
|
{
|
|
978
1020
|
messageId: message.id,
|
|
979
|
-
content: message.
|
|
1021
|
+
content: message.fallbackText,
|
|
980
1022
|
role: message.role,
|
|
981
1023
|
isHelpful: message.isHelpful
|
|
982
1024
|
}
|