semantic-renderer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +192 -0
  3. package/dist/core/classifier.d.ts +13 -0
  4. package/dist/core/classifier.d.ts.map +1 -0
  5. package/dist/core/classifier.js +478 -0
  6. package/dist/core/classifier.js.map +1 -0
  7. package/dist/core/index.d.ts +3 -0
  8. package/dist/core/index.d.ts.map +1 -0
  9. package/dist/core/index.js +3 -0
  10. package/dist/core/index.js.map +1 -0
  11. package/dist/core/types.d.ts +40 -0
  12. package/dist/core/types.d.ts.map +1 -0
  13. package/dist/core/types.js +2 -0
  14. package/dist/core/types.js.map +1 -0
  15. package/dist/react/FallbackMarkdown.d.ts +8 -0
  16. package/dist/react/FallbackMarkdown.d.ts.map +1 -0
  17. package/dist/react/FallbackMarkdown.js +10 -0
  18. package/dist/react/FallbackMarkdown.js.map +1 -0
  19. package/dist/react/SemanticRenderer.d.ts +14 -0
  20. package/dist/react/SemanticRenderer.d.ts.map +1 -0
  21. package/dist/react/SemanticRenderer.js +37 -0
  22. package/dist/react/SemanticRenderer.js.map +1 -0
  23. package/dist/react/index.d.ts +10 -0
  24. package/dist/react/index.d.ts.map +1 -0
  25. package/dist/react/index.js +11 -0
  26. package/dist/react/index.js.map +1 -0
  27. package/dist/react/renderers/CodeExplanationRenderer.d.ts +10 -0
  28. package/dist/react/renderers/CodeExplanationRenderer.d.ts.map +1 -0
  29. package/dist/react/renderers/CodeExplanationRenderer.js +14 -0
  30. package/dist/react/renderers/CodeExplanationRenderer.js.map +1 -0
  31. package/dist/react/renderers/ComparisonRenderer.d.ts +10 -0
  32. package/dist/react/renderers/ComparisonRenderer.d.ts.map +1 -0
  33. package/dist/react/renderers/ComparisonRenderer.js +13 -0
  34. package/dist/react/renderers/ComparisonRenderer.js.map +1 -0
  35. package/dist/react/renderers/DataTableRenderer.d.ts +10 -0
  36. package/dist/react/renderers/DataTableRenderer.d.ts.map +1 -0
  37. package/dist/react/renderers/DataTableRenderer.js +51 -0
  38. package/dist/react/renderers/DataTableRenderer.js.map +1 -0
  39. package/dist/react/renderers/ProsConsRenderer.d.ts +10 -0
  40. package/dist/react/renderers/ProsConsRenderer.d.ts.map +1 -0
  41. package/dist/react/renderers/ProsConsRenderer.js +13 -0
  42. package/dist/react/renderers/ProsConsRenderer.js.map +1 -0
  43. package/dist/react/renderers/StepsRenderer.d.ts +10 -0
  44. package/dist/react/renderers/StepsRenderer.d.ts.map +1 -0
  45. package/dist/react/renderers/StepsRenderer.js +28 -0
  46. package/dist/react/renderers/StepsRenderer.js.map +1 -0
  47. package/dist/react/renderers/VerdictRenderer.d.ts +10 -0
  48. package/dist/react/renderers/VerdictRenderer.d.ts.map +1 -0
  49. package/dist/react/renderers/VerdictRenderer.js +13 -0
  50. package/dist/react/renderers/VerdictRenderer.js.map +1 -0
  51. package/package.json +85 -0
  52. package/src/react/styles.css +79 -0
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { memo, useMemo } from 'react';
3
+ import { classify } from '../core/classifier.js';
4
+ import { FallbackMarkdown } from './FallbackMarkdown.js';
5
+ import { VerdictRenderer } from './renderers/VerdictRenderer.js';
6
+ import { ProsConsRenderer } from './renderers/ProsConsRenderer.js';
7
+ import { StepsRenderer } from './renderers/StepsRenderer.js';
8
+ import { ComparisonRenderer } from './renderers/ComparisonRenderer.js';
9
+ import { DataTableRenderer } from './renderers/DataTableRenderer.js';
10
+ import { CodeExplanationRenderer } from './renderers/CodeExplanationRenderer.js';
11
+ const RENDERER_MAP = {
12
+ 'comparison': ComparisonRenderer,
13
+ 'steps': StepsRenderer,
14
+ 'pros-cons': ProsConsRenderer,
15
+ 'code-explanation': CodeExplanationRenderer,
16
+ 'data-table': DataTableRenderer,
17
+ 'verdict': VerdictRenderer,
18
+ 'default': ({ block, Fallback }) => _jsx(Fallback, { content: block.rawMarkdown }),
19
+ };
20
+ export const SemanticRenderer = memo(({ content, isStreaming = false, className = '', fallback: Fallback = FallbackMarkdown, }) => {
21
+ // During streaming, bypass classification
22
+ if (isStreaming) {
23
+ return _jsx(Fallback, { content: content });
24
+ }
25
+ const blocks = useMemo(() => classify(content), [content]);
26
+ // If all blocks are default, skip the wrapper overhead
27
+ const allDefault = blocks.every(b => b.type === 'default');
28
+ if (allDefault) {
29
+ return _jsx(Fallback, { content: content });
30
+ }
31
+ return (_jsx("div", { className: `sem-body ${className}`.trim(), children: blocks.map(block => {
32
+ const Renderer = RENDERER_MAP[block.type] || RENDERER_MAP['default'];
33
+ return _jsx(Renderer, { block: block, Fallback: Fallback }, block.id);
34
+ }) }));
35
+ });
36
+ SemanticRenderer.displayName = 'SemanticRenderer';
37
+ //# sourceMappingURL=SemanticRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SemanticRenderer.js","sourceRoot":"","sources":["../../src/react/SemanticRenderer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAajF,MAAM,YAAY,GAAiI;IACjJ,YAAY,EAAE,kBAAkB;IAChC,OAAO,EAAE,aAAa;IACtB,WAAW,EAAE,gBAAgB;IAC7B,kBAAkB,EAAE,uBAAuB;IAC3C,YAAY,EAAE,iBAAiB;IAC/B,SAAS,EAAE,eAAe;IAC1B,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI;CAC7E,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,CAAC,EACpC,OAAO,EACP,WAAW,GAAG,KAAK,EACnB,SAAS,GAAG,EAAE,EACd,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,GACf,EAAE,EAAE;IAC1B,0CAA0C;IAC1C,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,KAAC,QAAQ,IAAC,OAAO,EAAE,OAAO,GAAI,CAAC;IACxC,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAE3D,uDAAuD;IACvD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAC3D,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,KAAC,QAAQ,IAAC,OAAO,EAAE,OAAO,GAAI,CAAC;IACxC,CAAC;IAED,OAAO,CACL,cAAK,SAAS,EAAE,YAAY,SAAS,EAAE,CAAC,IAAI,EAAE,YAC3C,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAClB,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;YACrE,OAAO,KAAC,QAAQ,IAAgB,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,IAA1C,KAAK,CAAC,EAAE,CAAsC,CAAC;QACvE,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { SemanticRenderer } from './SemanticRenderer.js';
2
+ export { VerdictRenderer } from './renderers/VerdictRenderer.js';
3
+ export { ProsConsRenderer } from './renderers/ProsConsRenderer.js';
4
+ export { StepsRenderer } from './renderers/StepsRenderer.js';
5
+ export { ComparisonRenderer } from './renderers/ComparisonRenderer.js';
6
+ export { DataTableRenderer } from './renderers/DataTableRenderer.js';
7
+ export { CodeExplanationRenderer } from './renderers/CodeExplanationRenderer.js';
8
+ export { classify } from '../core/index.js';
9
+ export type { SemanticBlock, SemanticBlockType, ComparisonMeta, StepsMeta, ProsConsMeta, CodeExplanationMeta, DataTableMeta, VerdictMeta, } from '../core/index.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,11 @@
1
+ // React entry — SemanticRenderer component + all renderers
2
+ export { SemanticRenderer } from './SemanticRenderer.js';
3
+ export { VerdictRenderer } from './renderers/VerdictRenderer.js';
4
+ export { ProsConsRenderer } from './renderers/ProsConsRenderer.js';
5
+ export { StepsRenderer } from './renderers/StepsRenderer.js';
6
+ export { ComparisonRenderer } from './renderers/ComparisonRenderer.js';
7
+ export { DataTableRenderer } from './renderers/DataTableRenderer.js';
8
+ export { CodeExplanationRenderer } from './renderers/CodeExplanationRenderer.js';
9
+ // Re-export core for convenience
10
+ export { classify } from '../core/index.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAEjF,iCAAiC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { SemanticBlock } from '../../core/types.js';
2
+ interface Props {
3
+ block: SemanticBlock;
4
+ Fallback: React.ComponentType<{
5
+ content: string;
6
+ }>;
7
+ }
8
+ export declare const CodeExplanationRenderer: import("react").MemoExoticComponent<({ block, Fallback }: Props) => import("react/jsx-runtime").JSX.Element>;
9
+ export {};
10
+ //# sourceMappingURL=CodeExplanationRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeExplanationRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/renderers/CodeExplanationRenderer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAuB,MAAM,qBAAqB,CAAC;AAE9E,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,uBAAuB,4DAA8B,KAAK,6CA6BrE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo } from 'react';
3
+ import { motion } from 'framer-motion';
4
+ import { Code2 } from 'lucide-react';
5
+ export const CodeExplanationRenderer = memo(({ block, Fallback }) => {
6
+ const meta = block.meta;
7
+ if (!meta?.code || !meta?.explanation) {
8
+ return _jsx(Fallback, { content: block.rawMarkdown });
9
+ }
10
+ const codeMd = '```' + (meta.language || '') + '\n' + meta.code + '\n```';
11
+ return (_jsxs(motion.div, { className: "sem-code-explain", initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3 }, children: [_jsxs("div", { className: "sem-code-panel", children: [_jsxs("div", { className: "sem-code-panel-header", children: [_jsx(Code2, { size: 14 }), _jsx("span", { children: meta.language || 'Code' })] }), _jsx(Fallback, { content: codeMd })] }), _jsxs("div", { className: "sem-explain-panel", children: [_jsx("div", { className: "sem-explain-panel-header", children: "Explanation" }), _jsx(Fallback, { content: meta.explanation })] })] }));
12
+ });
13
+ CodeExplanationRenderer.displayName = 'CodeExplanationRenderer';
14
+ //# sourceMappingURL=CodeExplanationRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeExplanationRenderer.js","sourceRoot":"","sources":["../../../src/react/renderers/CodeExplanationRenderer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAQrC,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS,EAAE,EAAE;IACzE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAsC,CAAC;IAE1D,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;QACtC,OAAO,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI,CAAC;IAClD,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;IAE1E,OAAO,CACL,MAAC,MAAM,CAAC,GAAG,IACT,SAAS,EAAC,kBAAkB,EAC5B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,aAE7B,eAAK,SAAS,EAAC,gBAAgB,aAC7B,eAAK,SAAS,EAAC,uBAAuB,aACpC,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,GAAI,EACnB,yBAAO,IAAI,CAAC,QAAQ,IAAI,MAAM,GAAQ,IAClC,EACN,KAAC,QAAQ,IAAC,OAAO,EAAE,MAAM,GAAI,IACzB,EACN,eAAK,SAAS,EAAC,mBAAmB,aAChC,cAAK,SAAS,EAAC,0BAA0B,4BAAkB,EAC3D,KAAC,QAAQ,IAAC,OAAO,EAAE,IAAI,CAAC,WAAW,GAAI,IACnC,IACK,CACd,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,uBAAuB,CAAC,WAAW,GAAG,yBAAyB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { SemanticBlock } from '../../core/types.js';
2
+ interface Props {
3
+ block: SemanticBlock;
4
+ Fallback: React.ComponentType<{
5
+ content: string;
6
+ }>;
7
+ }
8
+ export declare const ComparisonRenderer: import("react").MemoExoticComponent<({ block, Fallback }: Props) => import("react/jsx-runtime").JSX.Element>;
9
+ export {};
10
+ //# sourceMappingURL=ComparisonRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComparisonRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/renderers/ComparisonRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,qBAAqB,CAAC;AAIzE,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,kBAAkB,4DAA8B,KAAK,6CAqChE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo } from 'react';
3
+ import { motion } from 'framer-motion';
4
+ const ACCENT_COLORS = ['#6366f1', '#ec4899', '#14b8a6', '#f59e0b', '#8b5cf6'];
5
+ export const ComparisonRenderer = memo(({ block, Fallback }) => {
6
+ const meta = block.meta;
7
+ if (!meta?.items?.length || meta.items.length < 2) {
8
+ return _jsx(Fallback, { content: block.rawMarkdown });
9
+ }
10
+ return (_jsx(motion.div, { className: "sem-comparison", initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3 }, children: meta.items.map((item, i) => (_jsxs("div", { className: "sem-comparison-card", children: [_jsxs("div", { className: "sem-comparison-card-header", style: { borderColor: ACCENT_COLORS[i % ACCENT_COLORS.length] }, children: [_jsx("span", { className: "sem-comparison-card-dot", style: { background: ACCENT_COLORS[i % ACCENT_COLORS.length] } }), item.title] }), _jsx("ul", { className: "sem-comparison-card-points", children: item.points.map((point, j) => (_jsx("li", { className: "sem-comparison-card-point", children: _jsx(Fallback, { content: point }) }, j))) })] }, i))) }));
11
+ });
12
+ ComparisonRenderer.displayName = 'ComparisonRenderer';
13
+ //# sourceMappingURL=ComparisonRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComparisonRenderer.js","sourceRoot":"","sources":["../../../src/react/renderers/ComparisonRenderer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAO9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS,EAAE,EAAE;IACpE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAiC,CAAC;IAErD,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI,CAAC;IAClD,CAAC;IAED,OAAO,CACL,KAAC,MAAM,CAAC,GAAG,IACT,SAAS,EAAC,gBAAgB,EAC1B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,YAE5B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC3B,eAAa,SAAS,EAAC,qBAAqB,aAC1C,eACE,SAAS,EAAC,4BAA4B,EACtC,KAAK,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,aAE/D,eACE,SAAS,EAAC,yBAAyB,EACnC,KAAK,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,GAC9D,EACD,IAAI,CAAC,KAAK,IACP,EACN,aAAI,SAAS,EAAC,4BAA4B,YACvC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAC7B,aAAY,SAAS,EAAC,2BAA2B,YAC/C,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,GAAI,IADrB,CAAC,CAEL,CACN,CAAC,GACC,KAjBG,CAAC,CAkBL,CACP,CAAC,GACS,CACd,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { SemanticBlock } from '../../core/types.js';
2
+ interface Props {
3
+ block: SemanticBlock;
4
+ Fallback: React.ComponentType<{
5
+ content: string;
6
+ }>;
7
+ }
8
+ export declare const DataTableRenderer: import("react").MemoExoticComponent<({ block, Fallback }: Props) => import("react/jsx-runtime").JSX.Element>;
9
+ export {};
10
+ //# sourceMappingURL=DataTableRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTableRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/renderers/DataTableRenderer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AAExE,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAWD,eAAO,MAAM,iBAAiB,4DAA8B,KAAK,6CAoF/D,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo, useState, useMemo } from 'react';
3
+ import { motion } from 'framer-motion';
4
+ import { ArrowUpDown, ArrowUp, ArrowDown, Search } from 'lucide-react';
5
+ function naturalCompare(a, b) {
6
+ const numA = parseFloat(a);
7
+ const numB = parseFloat(b);
8
+ if (!isNaN(numA) && !isNaN(numB))
9
+ return numA - numB;
10
+ return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' });
11
+ }
12
+ export const DataTableRenderer = memo(({ block, Fallback }) => {
13
+ const meta = block.meta;
14
+ const [sortCol, setSortCol] = useState(null);
15
+ const [sortDir, setSortDir] = useState(null);
16
+ const [filter, setFilter] = useState('');
17
+ if (!meta?.headers?.length || !meta?.rows?.length) {
18
+ return _jsx(Fallback, { content: block.rawMarkdown });
19
+ }
20
+ const filteredRows = useMemo(() => {
21
+ let rows = meta.rows;
22
+ if (filter.trim()) {
23
+ const q = filter.toLowerCase();
24
+ rows = rows.filter(row => row.some(cell => cell.toLowerCase().includes(q)));
25
+ }
26
+ if (sortCol !== null && sortDir) {
27
+ rows = [...rows].sort((a, b) => {
28
+ const cmp = naturalCompare(a[sortCol] || '', b[sortCol] || '');
29
+ return sortDir === 'asc' ? cmp : -cmp;
30
+ });
31
+ }
32
+ return rows;
33
+ }, [meta.rows, filter, sortCol, sortDir]);
34
+ const handleSort = (colIdx) => {
35
+ if (sortCol === colIdx) {
36
+ if (sortDir === 'asc')
37
+ setSortDir('desc');
38
+ else {
39
+ setSortCol(null);
40
+ setSortDir(null);
41
+ }
42
+ }
43
+ else {
44
+ setSortCol(colIdx);
45
+ setSortDir('asc');
46
+ }
47
+ };
48
+ return (_jsxs(motion.div, { className: "sem-data-table", initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3 }, children: [_jsxs("div", { className: "sem-table-toolbar", children: [_jsxs("div", { className: "sem-table-filter", children: [_jsx(Search, { size: 14 }), _jsx("input", { type: "text", placeholder: "Filter rows...", value: filter, onChange: e => setFilter(e.target.value) })] }), _jsxs("span", { className: "sem-table-count", children: [filteredRows.length, " of ", meta.rows.length, " rows"] })] }), _jsx("div", { className: "sem-table-scroll", children: _jsxs("table", { children: [_jsx("thead", { children: _jsx("tr", { children: meta.headers.map((header, i) => (_jsxs("th", { className: "sem-sort-header", onClick: () => handleSort(i), children: [_jsx("span", { children: header }), sortCol === i && sortDir === 'asc' && _jsx(ArrowUp, { size: 12 }), sortCol === i && sortDir === 'desc' && _jsx(ArrowDown, { size: 12 }), sortCol !== i && _jsx(ArrowUpDown, { size: 12, className: "sem-sort-idle" })] }, i))) }) }), _jsx("tbody", { children: filteredRows.map((row, i) => (_jsx("tr", { children: row.map((cell, j) => (_jsx("td", { children: cell }, j))) }, i))) })] }) })] }));
49
+ });
50
+ DataTableRenderer.displayName = 'DataTableRenderer';
51
+ //# sourceMappingURL=DataTableRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTableRenderer.js","sourceRoot":"","sources":["../../../src/react/renderers/DataTableRenderer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { SemanticBlock } from '../../core/types.js';
2
+ interface Props {
3
+ block: SemanticBlock;
4
+ Fallback: React.ComponentType<{
5
+ content: string;
6
+ }>;
7
+ }
8
+ export declare const ProsConsRenderer: import("react").MemoExoticComponent<({ block, Fallback }: Props) => import("react/jsx-runtime").JSX.Element>;
9
+ export {};
10
+ //# sourceMappingURL=ProsConsRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProsConsRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/renderers/ProsConsRenderer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,qBAAqB,CAAC;AAEvE,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,gBAAgB,4DAA8B,KAAK,6CA6C9D,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo } from 'react';
3
+ import { motion } from 'framer-motion';
4
+ import { Check, X } from 'lucide-react';
5
+ export const ProsConsRenderer = memo(({ block, Fallback }) => {
6
+ const meta = block.meta;
7
+ if (!meta?.pros?.length || !meta?.cons?.length) {
8
+ return _jsx(Fallback, { content: block.rawMarkdown });
9
+ }
10
+ return (_jsxs(motion.div, { className: "sem-pros-cons", initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3 }, children: [_jsxs("div", { className: "sem-pros-col", children: [_jsxs("div", { className: "sem-pros-header", children: [_jsx(Check, { size: 18 }), _jsx("span", { children: "Pros" })] }), _jsx("ul", { className: "sem-pros-list", children: meta.pros.map((item, i) => (_jsxs("li", { className: "sem-pros-item", children: [_jsx(Check, { size: 14, className: "sem-pros-icon" }), _jsx("span", { children: _jsx(Fallback, { content: item }) })] }, i))) })] }), _jsxs("div", { className: "sem-cons-col", children: [_jsxs("div", { className: "sem-cons-header", children: [_jsx(X, { size: 18 }), _jsx("span", { children: "Cons" })] }), _jsx("ul", { className: "sem-cons-list", children: meta.cons.map((item, i) => (_jsxs("li", { className: "sem-cons-item", children: [_jsx(X, { size: 14, className: "sem-cons-icon" }), _jsx("span", { children: _jsx(Fallback, { content: item }) })] }, i))) })] })] }));
11
+ });
12
+ ProsConsRenderer.displayName = 'ProsConsRenderer';
13
+ //# sourceMappingURL=ProsConsRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProsConsRenderer.js","sourceRoot":"","sources":["../../../src/react/renderers/ProsConsRenderer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAQxC,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS,EAAE,EAAE;IAClE,MAAM,IAAI,GAAG,KAAK,CAAC,IAA+B,CAAC;IAEnD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC/C,OAAO,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI,CAAC;IAClD,CAAC;IAED,OAAO,CACL,MAAC,MAAM,CAAC,GAAG,IACT,SAAS,EAAC,eAAe,EACzB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,aAE7B,eAAK,SAAS,EAAC,cAAc,aAC3B,eAAK,SAAS,EAAC,iBAAiB,aAC9B,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,GAAI,EACnB,kCAAiB,IACb,EACN,aAAI,SAAS,EAAC,eAAe,YAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC1B,cAAY,SAAS,EAAC,eAAe,aACnC,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,eAAe,GAAG,EAC7C,yBAAM,KAAC,QAAQ,IAAC,OAAO,EAAE,IAAI,GAAI,GAAO,KAFjC,CAAC,CAGL,CACN,CAAC,GACC,IACD,EAEN,eAAK,SAAS,EAAC,cAAc,aAC3B,eAAK,SAAS,EAAC,iBAAiB,aAC9B,KAAC,CAAC,IAAC,IAAI,EAAE,EAAE,GAAI,EACf,kCAAiB,IACb,EACN,aAAI,SAAS,EAAC,eAAe,YAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC1B,cAAY,SAAS,EAAC,eAAe,aACnC,KAAC,CAAC,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,eAAe,GAAG,EACzC,yBAAM,KAAC,QAAQ,IAAC,OAAO,EAAE,IAAI,GAAI,GAAO,KAFjC,CAAC,CAGL,CACN,CAAC,GACC,IACD,IACK,CACd,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { SemanticBlock } from '../../core/types.js';
2
+ interface Props {
3
+ block: SemanticBlock;
4
+ Fallback: React.ComponentType<{
5
+ content: string;
6
+ }>;
7
+ }
8
+ export declare const StepsRenderer: import("react").MemoExoticComponent<({ block, Fallback }: Props) => import("react/jsx-runtime").JSX.Element>;
9
+ export {};
10
+ //# sourceMappingURL=StepsRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepsRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/renderers/StepsRenderer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,qBAAqB,CAAC;AAEpE,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,aAAa,4DAA8B,KAAK,6CA4D3D,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo, useState } from 'react';
3
+ import { motion, AnimatePresence } from 'framer-motion';
4
+ import { ChevronDown, ChevronRight } from 'lucide-react';
5
+ export const StepsRenderer = memo(({ block, Fallback }) => {
6
+ const meta = block.meta;
7
+ const [expandedSteps, setExpandedSteps] = useState(() => new Set(meta?.steps?.map((_, i) => i) ?? []));
8
+ if (!meta?.steps?.length) {
9
+ return _jsx(Fallback, { content: block.rawMarkdown });
10
+ }
11
+ const toggleStep = (index) => {
12
+ setExpandedSteps(prev => {
13
+ const next = new Set(prev);
14
+ if (next.has(index))
15
+ next.delete(index);
16
+ else
17
+ next.add(index);
18
+ return next;
19
+ });
20
+ };
21
+ return (_jsx(motion.div, { className: "sem-steps", initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3 }, children: meta.steps.map((step, i) => {
22
+ const isExpanded = expandedSteps.has(i);
23
+ const isLast = i === meta.steps.length - 1;
24
+ return (_jsxs("div", { className: `sem-step ${isLast ? 'sem-step-last' : ''}`, children: [_jsxs("div", { className: "sem-step-rail", children: [_jsx("div", { className: "sem-step-circle", children: step.number }), !isLast && _jsx("div", { className: "sem-step-line" })] }), _jsxs("div", { className: "sem-step-content", children: [_jsxs("button", { className: "sem-step-title", onClick: () => toggleStep(i), children: [_jsx("span", { children: step.title }), isExpanded ? _jsx(ChevronDown, { size: 16 }) : _jsx(ChevronRight, { size: 16 })] }), _jsx(AnimatePresence, { initial: false, children: isExpanded && step.body && (_jsx(motion.div, { className: "sem-step-body", initial: { height: 0, opacity: 0 }, animate: { height: 'auto', opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2 }, children: _jsx(Fallback, { content: step.body }) })) })] })] }, i));
25
+ }) }));
26
+ });
27
+ StepsRenderer.displayName = 'StepsRenderer';
28
+ //# sourceMappingURL=StepsRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepsRenderer.js","sourceRoot":"","sources":["../../../src/react/renderers/StepsRenderer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { SemanticBlock } from '../../core/types.js';
2
+ interface Props {
3
+ block: SemanticBlock;
4
+ Fallback: React.ComponentType<{
5
+ content: string;
6
+ }>;
7
+ }
8
+ export declare const VerdictRenderer: import("react").MemoExoticComponent<({ block, Fallback }: Props) => import("react/jsx-runtime").JSX.Element>;
9
+ export {};
10
+ //# sourceMappingURL=VerdictRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerdictRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/renderers/VerdictRenderer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,qBAAqB,CAAC;AAEtE,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,eAAe,4DAA8B,KAAK,6CA2B7D,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo } from 'react';
3
+ import { motion } from 'framer-motion';
4
+ import { Lightbulb } from 'lucide-react';
5
+ export const VerdictRenderer = memo(({ block, Fallback }) => {
6
+ const meta = block.meta;
7
+ if (!meta?.verdict) {
8
+ return _jsx(Fallback, { content: block.rawMarkdown });
9
+ }
10
+ return (_jsxs(motion.div, { className: "sem-verdict", initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3 }, children: [_jsx("div", { className: "sem-verdict-icon", children: _jsx(Lightbulb, { size: 20 }) }), _jsxs("div", { className: "sem-verdict-content", children: [_jsx(Fallback, { content: meta.verdict }), meta.reasoning && (_jsx("div", { className: "sem-verdict-reasoning", children: _jsx(Fallback, { content: meta.reasoning }) }))] })] }));
11
+ });
12
+ VerdictRenderer.displayName = 'VerdictRenderer';
13
+ //# sourceMappingURL=VerdictRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerdictRenderer.js","sourceRoot":"","sources":["../../../src/react/renderers/VerdictRenderer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQzC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS,EAAE,EAAE;IACjE,MAAM,IAAI,GAAG,KAAK,CAAC,IAA8B,CAAC;IAElD,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;QACnB,OAAO,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI,CAAC;IAClD,CAAC;IAED,OAAO,CACL,MAAC,MAAM,CAAC,GAAG,IACT,SAAS,EAAC,aAAa,EACvB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,aAE7B,cAAK,SAAS,EAAC,kBAAkB,YAC/B,KAAC,SAAS,IAAC,IAAI,EAAE,EAAE,GAAI,GACnB,EACN,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAI,EAClC,IAAI,CAAC,SAAS,IAAI,CACjB,cAAK,SAAS,EAAC,uBAAuB,YACpC,KAAC,QAAQ,IAAC,OAAO,EAAE,IAAI,CAAC,SAAS,GAAI,GACjC,CACP,IACG,IACK,CACd,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,eAAe,CAAC,WAAW,GAAG,iBAAiB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "semantic-renderer",
3
+ "version": "1.0.0",
4
+ "description": "Intelligent LLM response renderer that detects semantic intent (comparisons, steps, pros/cons, code explanations, tables, verdicts) and renders with purpose-built visual components instead of generic markdown.",
5
+ "author": "Sagar Kalra <autopriseai@gmail.com>",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/AutoPriseAI/semantic-renderer"
10
+ },
11
+ "keywords": [
12
+ "llm",
13
+ "ai",
14
+ "markdown",
15
+ "renderer",
16
+ "semantic",
17
+ "react",
18
+ "react-native",
19
+ "chatbot",
20
+ "comparison",
21
+ "steps",
22
+ "pros-cons",
23
+ "streaming",
24
+ "openai",
25
+ "claude",
26
+ "gemini"
27
+ ],
28
+ "type": "module",
29
+ "main": "./dist/core/index.js",
30
+ "module": "./dist/core/index.js",
31
+ "types": "./dist/core/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/core/index.d.ts",
35
+ "import": "./dist/core/index.js"
36
+ },
37
+ "./react": {
38
+ "types": "./dist/react/index.d.ts",
39
+ "import": "./dist/react/index.js"
40
+ },
41
+ "./react/styles.css": "./src/react/styles.css"
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "src/react/styles.css",
46
+ "README.md",
47
+ "LICENSE"
48
+ ],
49
+ "scripts": {
50
+ "build": "tsc",
51
+ "prepublishOnly": "npm run build"
52
+ },
53
+ "peerDependencies": {
54
+ "framer-motion": ">=10.0.0",
55
+ "lucide-react": ">=0.300.0",
56
+ "react": ">=18.0.0",
57
+ "react-dom": ">=18.0.0",
58
+ "react-markdown": ">=9.0.0"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "react": {
62
+ "optional": true
63
+ },
64
+ "react-dom": {
65
+ "optional": true
66
+ },
67
+ "react-markdown": {
68
+ "optional": true
69
+ },
70
+ "framer-motion": {
71
+ "optional": true
72
+ },
73
+ "lucide-react": {
74
+ "optional": true
75
+ }
76
+ },
77
+ "devDependencies": {
78
+ "@types/react": "^19.0.0",
79
+ "framer-motion": "^12.38.0",
80
+ "lucide-react": "^1.7.0",
81
+ "react-dom": "^19.2.5",
82
+ "react-markdown": "^10.1.0",
83
+ "typescript": "^5.9.0"
84
+ }
85
+ }
@@ -0,0 +1,79 @@
1
+ /* semantic-renderer — default styles
2
+ Import: import 'semantic-renderer/react/styles.css'
3
+ All classes use .sem- prefix to avoid collisions. */
4
+
5
+ .sem-body { display: flex; flex-direction: column; gap: 16px; }
6
+
7
+ /* Verdict */
8
+ .sem-verdict { display: flex; gap: 14px; padding: 16px 18px; border-left: 4px solid var(--sem-accent, #6366f1); background: linear-gradient(135deg, rgba(99,102,241,0.04) 0%, rgba(109,40,217,0.03) 100%); border-radius: 0 10px 10px 0; }
9
+ .sem-verdict-icon { flex-shrink: 0; color: var(--sem-accent, #6366f1); margin-top: 2px; }
10
+ .sem-verdict-content { flex: 1; min-width: 0; }
11
+ .sem-verdict-content p { font-size: 1.02em; }
12
+ .sem-verdict-reasoning { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--sem-border, #e5e7eb); opacity: 0.75; font-size: 0.92em; }
13
+
14
+ /* Pros & Cons */
15
+ .sem-pros-cons { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
16
+ .sem-pros-col, .sem-cons-col { border-radius: 10px; border: 1px solid var(--sem-border, #e5e7eb); overflow: hidden; }
17
+ .sem-pros-header, .sem-cons-header { display: flex; align-items: center; gap: 8px; padding: 10px 14px; font-weight: 600; font-size: 0.88em; text-transform: uppercase; letter-spacing: 0.04em; }
18
+ .sem-pros-header { background: rgba(22,163,74,0.08); color: #16a34a; border-bottom: 1px solid rgba(22,163,74,0.15); }
19
+ .sem-cons-header { background: rgba(220,38,38,0.08); color: #dc2626; border-bottom: 1px solid rgba(220,38,38,0.15); }
20
+ .sem-pros-list, .sem-cons-list { list-style: none; padding: 8px 14px; margin: 0; }
21
+ .sem-pros-item, .sem-cons-item { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--sem-border, #e5e7eb); font-size: 0.93em; line-height: 1.5; }
22
+ .sem-pros-item:last-child, .sem-cons-item:last-child { border-bottom: none; }
23
+ .sem-pros-icon { flex-shrink: 0; color: #16a34a; margin-top: 3px; }
24
+ .sem-cons-icon { flex-shrink: 0; color: #dc2626; margin-top: 3px; }
25
+
26
+ /* Steps */
27
+ .sem-steps { display: flex; flex-direction: column; }
28
+ .sem-step { display: flex; gap: 14px; min-height: 48px; }
29
+ .sem-step-rail { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; width: 32px; }
30
+ .sem-step-circle { width: 28px; height: 28px; border-radius: 50%; background: var(--sem-accent, #6366f1); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 0.78em; font-weight: 700; flex-shrink: 0; }
31
+ .sem-step-line { width: 2px; flex: 1; background: var(--sem-border, #d1d5db); margin: 4px 0; min-height: 16px; }
32
+ .sem-step-last .sem-step-line { display: none; }
33
+ .sem-step-content { flex: 1; min-width: 0; padding-bottom: 16px; }
34
+ .sem-step-last .sem-step-content { padding-bottom: 0; }
35
+ .sem-step-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; background: none; border: none; cursor: pointer; font: inherit; font-weight: 600; font-size: 0.95em; color: inherit; padding: 4px 8px 4px 0; text-align: left; border-radius: 6px; transition: background 0.15s; }
36
+ .sem-step-title:hover { background: rgba(0,0,0,0.03); }
37
+ .sem-step-title svg { flex-shrink: 0; opacity: 0.5; }
38
+ .sem-step-body { overflow: hidden; padding-top: 6px; }
39
+ .sem-step-body p { font-size: 0.93em; }
40
+
41
+ /* Comparison */
42
+ .sem-comparison { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
43
+ .sem-comparison-card { border-radius: 10px; border: 1px solid var(--sem-border, #e5e7eb); overflow: hidden; }
44
+ .sem-comparison-card-header { display: flex; align-items: center; gap: 8px; padding: 10px 14px; font-weight: 600; font-size: 0.95em; border-bottom: 2px solid var(--sem-accent, #6366f1); background: rgba(0,0,0,0.015); }
45
+ .sem-comparison-card-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
46
+ .sem-comparison-card-points { list-style: none; padding: 8px 14px; margin: 0; }
47
+ .sem-comparison-card-point { padding: 6px 0; border-bottom: 1px solid var(--sem-border, #e5e7eb); font-size: 0.92em; line-height: 1.5; }
48
+ .sem-comparison-card-point:last-child { border-bottom: none; }
49
+
50
+ /* Data Table */
51
+ .sem-data-table { border-radius: 10px; border: 1px solid var(--sem-border, #e5e7eb); overflow: hidden; }
52
+ .sem-table-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 12px; background: rgba(0,0,0,0.015); border-bottom: 1px solid var(--sem-border, #e5e7eb); }
53
+ .sem-table-filter { display: flex; align-items: center; gap: 6px; color: #6b7280; }
54
+ .sem-table-filter input { border: 1px solid var(--sem-border, #d1d5db); border-radius: 6px; padding: 4px 8px; font-size: 0.82em; outline: none; width: 160px; }
55
+ .sem-table-filter input:focus { border-color: var(--sem-accent, #6366f1); }
56
+ .sem-table-count { font-size: 0.78em; color: #6b7280; white-space: nowrap; }
57
+ .sem-table-scroll { overflow-x: auto; }
58
+ .sem-sort-header { cursor: pointer; user-select: none; white-space: nowrap; }
59
+ .sem-sort-header > span { margin-right: 4px; }
60
+ .sem-sort-idle { opacity: 0.3; }
61
+ .sem-sort-header:hover .sem-sort-idle { opacity: 0.6; }
62
+
63
+ /* Code + Explanation */
64
+ .sem-code-explain { display: grid; grid-template-columns: 55% 45%; border-radius: 10px; border: 1px solid var(--sem-border, #e5e7eb); overflow: hidden; }
65
+ .sem-code-panel { border-right: 1px solid var(--sem-border, #e5e7eb); overflow: auto; max-height: 500px; }
66
+ .sem-code-panel-header { display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: #1e1e1e; color: #9ca3af; font-size: 0.78em; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; }
67
+ .sem-explain-panel { padding: 14px 16px; overflow: auto; max-height: 500px; }
68
+ .sem-explain-panel-header { font-weight: 600; font-size: 0.82em; text-transform: uppercase; letter-spacing: 0.04em; color: #6b7280; margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--sem-border, #e5e7eb); }
69
+ .sem-explain-panel p { font-size: 0.92em; }
70
+
71
+ /* Responsive */
72
+ @media (max-width: 700px) {
73
+ .sem-pros-cons { grid-template-columns: 1fr; }
74
+ .sem-comparison { grid-template-columns: 1fr; }
75
+ .sem-code-explain { grid-template-columns: 1fr; }
76
+ .sem-code-panel { border-right: none; border-bottom: 1px solid var(--sem-border, #e5e7eb); max-height: 300px; }
77
+ .sem-explain-panel { max-height: none; }
78
+ .sem-table-toolbar { flex-direction: column; align-items: flex-start; }
79
+ }