{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "excel-splitting-viewer-block",
  "title": "Excel Splitting",
  "description": "One Excel workbook fanned out into several clean CSVs — each reconstructed table rendered in the viewer, with a sidebar listing every CSV the splitter emitted, the sheet it was carved from, and how it was reconstructed. Selecting one opens that CSV.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "@retab/file-viewer",
    "@retab/csv-viewer",
    "@retab/xlsx-viewer",
    "@retab/segments"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/blocks/excel-splitting-viewer-block.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { FileSpreadsheet, TableProperties } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { CsvViewerDocument } from \"@/components/ui/csv-viewer\";\nimport {\n  FileViewer,\n  FileViewerContent,\n  FileViewerControls,\n  FileViewerHeader,\n  FileViewerInset,\n  FileViewerProvider,\n  FileViewerSidebar,\n  FileViewerSidebarContent,\n  FileViewerSidebarTrigger,\n  FileViewerTitle,\n  FileViewerViewport,\n} from \"@/components/ui/file-viewer\";\nimport { XlsxViewer } from \"@/components/ui/xlsx-viewer\";\nimport { SEGMENT_PALETTE } from \"@/lib/segments\";\nimport csvOutputs from \"@/components/viewers/sample-data/excel-splitting.json\";\n\nconst WORKBOOK_ID = \"workbook\";\nconst WORKBOOK_NAME = \"nvidia-financials-fy2024.xlsx\";\nconst XLSX_URL = \"/samples/nvidia-financials-fy2024.xlsx\";\n\nconst WORKBOOK_SOURCE = {\n  kind: \"url\" as const,\n  url: XLSX_URL,\n  fileName: WORKBOOK_NAME,\n};\n\ntype CsvId = keyof typeof csvOutputs;\n\n/**\n * One CSV the Excel splitter emitted. `sheetLabel` is the workbook sheet it was\n * carved from; `enrichment` is the reconstruction step that turned that raw\n * sheet into a clean, partition-ready table. The CSV text itself lives in the\n * sample-data JSON, keyed by `id`.\n */\ntype CsvOutput = {\n  id: CsvId;\n  fileName: string;\n  sheetLabel: string;\n  enrichment: string;\n};\n\nconst CSV_OUTPUTS: CsvOutput[] = [\n  {\n    id: \"income-statement\",\n    fileName: \"income-statement.csv\",\n    sheetLabel: \"Consolidated Statements of Income\",\n    enrichment: \"Period columns flattened to one header\",\n  },\n  {\n    id: \"comprehensive-income\",\n    fileName: \"comprehensive-income.csv\",\n    sheetLabel: \"Consolidated Statements of Comprehensive Income\",\n    enrichment: \"Section banners kept as label rows\",\n  },\n  {\n    id: \"balance-sheet\",\n    fileName: \"balance-sheet.csv\",\n    sheetLabel: \"Consolidated Balance Sheets\",\n    enrichment: \"Merged title cell dropped\",\n  },\n  {\n    id: \"shareholders-equity\",\n    fileName: \"shareholders-equity.csv\",\n    sheetLabel: \"Consolidated Statements of Shareholders' Equity\",\n    enrichment: \"Equity-component matrix melted to columns\",\n  },\n  {\n    id: \"cash-flows\",\n    fileName: \"cash-flows.csv\",\n    sheetLabel: \"Consolidated Statements of Cash Flows\",\n    enrichment: \"Blank filler cells cleared\",\n  },\n];\n\n// Stable {kind:\"text\"} source per CSV so selecting one swaps the document\n// without re-creating the viewer resource on every render.\nconst CSV_SOURCE_BY_ID = new Map(\n  CSV_OUTPUTS.map((output) => [\n    output.id,\n    {\n      kind: \"text\" as const,\n      text: csvOutputs[output.id],\n      fileName: output.fileName,\n    },\n  ]),\n);\n\nfunction csvShape(id: CsvId) {\n  const lines = csvOutputs[id].split(\"\\n\");\n  return { rows: lines.length, cols: lines[0]?.split(\",\").length ?? 0 };\n}\n\nfunction outputColor(index: number) {\n  return SEGMENT_PALETTE[index % SEGMENT_PALETTE.length];\n}\n\n/**\n * Excel splitting block — one Excel workbook fanned out into several clean CSVs.\n * A left sidebar lists the source workbook first, then every CSV the splitter\n * emitted. Selecting an entry swaps the main viewer to that document: the XLSX\n * viewer for the workbook, the CSV viewer for each output.\n */\nexport function ExcelSplittingViewerBlock() {\n  const [activeId, setActiveId] = React.useState<string>(WORKBOOK_ID);\n  const isWorkbook = activeId === WORKBOOK_ID;\n  const activeSource = isWorkbook\n    ? WORKBOOK_SOURCE\n    : CSV_SOURCE_BY_ID.get(activeId as CsvId)!;\n\n  return (\n    <FileViewerProvider source={activeSource} defaultSidebarOpen>\n      <FileViewer className=\"bg-background h-full min-h-[680px]\">\n        <FileViewerHeader>\n          <FileViewerSidebarTrigger className=\"-ms-1\" />\n          <FileViewerTitle />\n          <FileViewerControls />\n        </FileViewerHeader>\n        <FileViewerContent>\n          <FileViewerSidebar\n            aria-label=\"Split output\"\n            side=\"left\"\n            width=\"300px\"\n          >\n            <FileViewerSidebarContent className=\"gap-0 p-0\">\n              <div className=\"border-b px-4 py-3\">\n                <p className=\"text-sm font-medium\">Split output</p>\n                <p className=\"text-muted-foreground text-xs\">\n                  Source workbook &rarr; {CSV_OUTPUTS.length} CSVs\n                </p>\n              </div>\n              <ul className=\"min-h-0 flex-1 overflow-y-auto\">\n                <li>\n                  <WorkbookRow\n                    active={isWorkbook}\n                    onSelect={() => setActiveId(WORKBOOK_ID)}\n                  />\n                </li>\n                <li>\n                  <p className=\"text-muted-foreground/70 border-y px-4 pt-3 pb-1 text-[11px] font-medium tracking-wide uppercase\">\n                    Reconstructed CSVs\n                  </p>\n                </li>\n                {CSV_OUTPUTS.map((output, index) => {\n                  const { rows, cols } = csvShape(output.id);\n                  return (\n                    <li key={output.id}>\n                      <CsvOutputRow\n                        output={output}\n                        color={outputColor(index)}\n                        rows={rows}\n                        cols={cols}\n                        active={output.id === activeId}\n                        onSelect={() => setActiveId(output.id)}\n                      />\n                    </li>\n                  );\n                })}\n              </ul>\n            </FileViewerSidebarContent>\n          </FileViewerSidebar>\n          <FileViewerInset>\n            <FileViewerViewport>\n              {isWorkbook ? (\n                <XlsxViewer\n                  source={WORKBOOK_SOURCE}\n                  bare\n                  controls={false}\n                  fallbackSheetTabs\n                  className=\"h-full\"\n                />\n              ) : (\n                <CsvViewerDocument\n                  source={activeSource}\n                  fillHeight\n                  controls={false}\n                  className=\"h-full\"\n                />\n              )}\n            </FileViewerViewport>\n          </FileViewerInset>\n        </FileViewerContent>\n      </FileViewer>\n    </FileViewerProvider>\n  );\n}\n\n/** The source workbook — the first sidebar entry. */\nfunction WorkbookRow({\n  active,\n  onSelect,\n}: {\n  active: boolean;\n  onSelect: () => void;\n}) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onSelect}\n      aria-pressed={active}\n      className={cn(\n        \"focus-visible:ring-ring relative flex w-full items-center gap-2.5 px-4 py-3 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none\",\n        active ? \"bg-muted/60\" : \"hover:bg-muted/40\",\n      )}\n    >\n      <span\n        aria-hidden\n        className={cn(\n          \"bg-foreground absolute inset-y-0 left-0 w-0.5 transition-opacity\",\n          active ? \"opacity-100\" : \"opacity-0\",\n        )}\n      />\n      <FileSpreadsheet className=\"text-muted-foreground size-4 shrink-0\" />\n      <span className=\"min-w-0 flex-1\">\n        <span className=\"text-foreground block truncate font-mono text-sm\">\n          {WORKBOOK_NAME}\n        </span>\n        <span className=\"text-muted-foreground block truncate text-xs\">\n          Source workbook\n        </span>\n      </span>\n    </button>\n  );\n}\n\n/** One reconstructed CSV in the sidebar. */\nfunction CsvOutputRow({\n  output,\n  color,\n  rows,\n  cols,\n  active,\n  onSelect,\n}: {\n  output: CsvOutput;\n  color: string;\n  rows: number;\n  cols: number;\n  active: boolean;\n  onSelect: () => void;\n}) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onSelect}\n      aria-pressed={active}\n      className={cn(\n        \"focus-visible:ring-ring relative flex w-full flex-col gap-1.5 px-4 py-3 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none\",\n        active ? \"bg-muted/60\" : \"hover:bg-muted/40\",\n      )}\n    >\n      <span\n        aria-hidden\n        className={cn(\n          \"absolute inset-y-0 left-0 w-0.5 transition-opacity\",\n          active ? \"opacity-100\" : \"opacity-0\",\n        )}\n        style={{ backgroundColor: color }}\n      />\n      <div className=\"flex items-center gap-2\">\n        <span\n          aria-hidden\n          className=\"size-2.5 shrink-0 rounded-full\"\n          style={{ backgroundColor: color }}\n        />\n        <span className=\"text-foreground truncate font-mono text-sm\">\n          {output.fileName}\n        </span>\n        <span className=\"text-muted-foreground ml-auto inline-flex items-center gap-1 font-mono text-[11px]\">\n          <TableProperties className=\"size-3\" />\n          {rows}&times;{cols}\n        </span>\n      </div>\n      <div className=\"text-muted-foreground truncate pl-[18px] text-xs\">\n        {output.sheetLabel}\n      </div>\n      <div className=\"text-muted-foreground/80 truncate pl-[18px] text-[11px]\">\n        {output.enrichment}\n      </div>\n    </button>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/blocks/excel-splitting-viewer-block.tsx"
    },
    {
      "path": "components/viewers/sample-data/excel-splitting.json",
      "content": "{\n  \"income-statement\": \"Line item,\\\"Jan 28, 2024\\\",\\\"Jan 29, 2023\\\",\\\"Jan 30, 2022\\\"\\nIncome Statement [Abstract],,,\\nRevenue,60922,26974,26914\\nCost of revenue,16621,11618,9439\\nGross profit,44301,15356,17475\\nOperating expenses,,,\\nResearch and development,8675,7339,5268\\n\\\"Sales, general and administrative\\\",2654,2440,2166\\nAcquisition termination cost,0,1353,0\\nTotal operating expenses,11329,11132,7434\\nOperating income,32972,4224,10041\\nInterest income,866,267,29\\nInterest expense,-257,-262,-236\\n\\\"Other, net\\\",237,-48,107\\n\\\"Other income (expense), net\\\",846,-43,-100\\nIncome before income tax,33818,4181,9941\\nIncome tax expense (benefit),4058,-187,189\\nNet income,29760,4368,9752\\nNet income per share:,,,\\nBasic (in USD per share),12.05,1.76,3.91\\nDiluted (in USD per share),11.93,1.74,3.85\\nWeighted average shares used in per share computation:,,,\\nBasic (in shares),2469,2487,2496\\nDiluted (in shares),2494,2507,2535\",\n  \"comprehensive-income\": \"Line item,\\\"Jan 28, 2024\\\",\\\"Jan 29, 2023\\\",\\\"Jan 30, 2022\\\"\\nStatement of Comprehensive Income [Abstract],,,\\nNet income,29760,4368,9752\\nAvailable-for-sale securities:,,,\\nNet change in unrealized gain (loss),80,-31,-16\\nReclassification adjustments for net realized gain included in net income,0,1,0\\nNet change in unrealized gain (loss),80,-30,-16\\nCash flow hedges:,,,\\nNet change in unrealized gain (loss),38,47,-43\\nReclassification adjustments for net realized gain (loss) included in net income,-48,-49,29\\nNet change in unrealized loss,-10,-2,-14\\n\\\"Other comprehensive income (loss), net of tax\\\",70,-32,-30\\nTotal comprehensive income,29830,4336,9722\",\n  \"balance-sheet\": \"Line item,\\\"Jan 28, 2024\\\",\\\"Jan 29, 2023\\\"\\nCurrent assets:,,\\nCash and cash equivalents,7280,3389\\nMarketable securities,18704,9907\\n\\\"Accounts receivable, net\\\",9999,3827\\nInventories,5282,5159\\nPrepaid expenses and other current assets,3080,791\\nTotal current assets,44345,23073\\n\\\"Property and equipment, net\\\",3914,3807\\nOperating lease assets,1346,1038\\nGoodwill,4430,4372\\n\\\"Intangible assets, net\\\",1112,1676\\nDeferred income tax assets,6081,3396\\nOther assets,4500,3820\\nTotal assets,65728,41182\\nCurrent liabilities:,,\\nAccounts payable,2699,1193\\nAccrued and other current liabilities,6682,4120\\nShort-term debt,1250,1250\\nTotal current liabilities,10631,6563\\nLong-term debt,8459,9703\\nLong-term operating lease liabilities,1119,902\\nOther long-term liabilities,2541,1913\\nTotal liabilities,22750,19081\\nCommitments and contingencies - see Note 13,,\\nShareholders&#8217; equity:,,\\n\\\"Preferred stock, $0.001 par value; 2 shares authorized; none issued\\\",0,0\\n\\\"Common stock, $0.001 par value; 8,000 shares authorized; 2,464 shares issued and outstanding as of January 28, 2024; 2,466 shares issued and outstanding as of January 29, 2023\\\",2,2\\nAdditional paid-in capital,13132,11971\\nAccumulated other comprehensive income (loss),27,-43\\nRetained earnings,29817,10171\\nTotal shareholders' equity,42978,22101\\nTotal liabilities and shareholders' equity,65728,41182\",\n  \"shareholders-equity\": \"Line item,Total,Common Stock Outstanding,Additional Paid-in Capital,Treasury Stock,Accumulated Other Comprehensive Income (Loss),Retained Earnings\\n\\\"Beginning balance, common stock outstanding (in shares) at Jan. 31, 2021\\\",,2479,,,,\\n\\\"Beginning balances, shareholders' equity at Jan. 31, 2021\\\",16893,3,8719,-10756,19,18908\\nIncrease (Decrease) in Shareholders' Equity,,,,,,\\nNet income,9752,,,,,9752\\nOther comprehensive (loss) income,-30,,,,-30,\\nIssuance of common stock from stock plans (in shares),,35,,,,\\nIssuance of common stock from stock plans,281,,281,,,\\nTax withholding related to vesting of restricted stock units (in shares),,-8,,,,\\nTax withholding related to vesting of restricted stock units,-1904,,-614,-1290,,\\nCash dividends declared and paid,-399,,,,,-399\\nFair value of partially vested equity awards assumed in connection with acquisitions,18,,18,,,\\nStock-based compensation,2001,,2001,,,\\nRetirement of Treasury Stock,0,,-20,12046,,-12026\\n\\\"Ending balance, common stock outstanding (in shares) at Jan. 30, 2022\\\",,2506,,,,\\n\\\"Ending balances, shareholders' equity at Jan. 30, 2022\\\",26612,3,10385,0,-11,16235\\nIncrease (Decrease) in Shareholders' Equity,,,,,,\\nCash dividends declared and paid (USD per common share),0.16,,,,,\\nNet income,4368,,,,,4368\\nOther comprehensive (loss) income,-32,,,,-32,\\nIssuance of common stock from stock plans (in shares),,31,,,,\\nIssuance of common stock from stock plans,355,,355,,,\\nTax withholding related to vesting of restricted stock units (in shares),,-8,,,,\\nTax withholding related to vesting of restricted stock units,-1475,,-1475,,,\\nShare repurchased (in shares),,-63,,,,\\nShares repurchased,-10039,-1,-4,,,-10034\\nCash dividends declared and paid,-398,,,,,-398\\nStock-based compensation,2710,,2710,,,\\n\\\"Ending balance, common stock outstanding (in shares) at Jan. 29, 2023\\\",2466,2466,,,,\\n\\\"Ending balances, shareholders' equity at Jan. 29, 2023\\\",22101,2,11971,0,-43,10171\\nIncrease (Decrease) in Shareholders' Equity,,,,,,\\nCash dividends declared and paid (USD per common share),0.16,,,,,\\nNet income,29760,,,,,29760\\nOther comprehensive (loss) income,70,,,,70,\\nIssuance of common stock from stock plans (in shares),,26,,,,\\nIssuance of common stock from stock plans,403,,403,,,\\nTax withholding related to vesting of restricted stock units (in shares),,-7,,,,\\nTax withholding related to vesting of restricted stock units,-2783,,-2783,,,\\nShare repurchased (in shares),-21,-21,,,,\\nShares repurchased,-9746,,-27,,,-9719\\nCash dividends declared and paid,-395,,,,,-395\\nStock-based compensation,3568,,3568,,,\\n\\\"Ending balance, common stock outstanding (in shares) at Jan. 28, 2024\\\",2464,2464,,,,\\n\\\"Ending balances, shareholders' equity at Jan. 28, 2024\\\",42978,2,13132,0,27,29817\\nIncrease (Decrease) in Shareholders' Equity,,,,,,\\nCash dividends declared and paid (USD per common share),0.16,,,,,\",\n  \"cash-flows\": \"Line item,\\\"Jan 28, 2024\\\",\\\"Jan 29, 2023\\\",\\\"Jan 30, 2022\\\"\\nCash flows from operating activities:,,,\\nNet income,29760,4368,9752\\nAdjustments to reconcile net income to net cash provided by operating activities:,,,\\nStock-based compensation expense,3549,2709,2004\\nDepreciation and amortization,1508,1544,1174\\nDeferred income taxes,-2489,-2164,-406\\n\\\"(Gains) losses on investments in non-affiliated entities, net\\\",-238,45,-100\\nAcquisition termination cost,0,1353,0\\nOther,-278,-7,47\\n\\\"Changes in operating assets and liabilities, net of acquisitions:\\\",,,\\nAccounts receivable,-6172,822,-2215\\nInventories,-98,-2554,-774\\nPrepaid expenses and other assets,-1522,-1517,-1715\\nAccounts payable,1531,-551,568\\nAccrued and other current liabilities,2025,1341,581\\nOther long-term liabilities,514,252,192\\nNet cash provided by operating activities,28090,5641,9108\\nCash flows from investing activities:,,,\\nProceeds from maturities of marketable securities,9732,19425,15197\\nProceeds from sales of marketable securities,50,1806,1023\\nPurchases of marketable securities,-18211,-11897,-24787\\nPurchases related to property and equipment and intangible assets,-1069,-1833,-976\\n\\\"Acquisitions, net of cash acquired\\\",-83,-49,-263\\n\\\"Investments in non-affiliated entities and other, net\\\",-985,-77,-24\\nNet cash provided by (used in) investing activities,-10566,7375,-9830\\nCash flows from financing activities:,,,\\nProceeds related to employee stock plans,403,355,281\\nPayments related to repurchases of common stock,-9533,-10039,0\\nPayments related to tax on restricted stock units,-2783,-1475,-1904\\nRepayment of debt,-1250,0,-1000\\nDividends paid,-395,-398,-399\\nPrincipal payments on property and equipment and intangible assets,-74,-58,-83\\n\\\"Issuance of debt, net of issuance costs\\\",0,0,4977\\nOther,-1,-2,-7\\nNet cash provided by (used in) financing activities,-13633,-11617,1865\\nChange in cash and cash equivalents,3891,1399,1143\\nCash and cash equivalents at beginning of period,3389,1990,847\\nCash and cash equivalents at end of period,7280,3389,1990\\nSupplemental disclosures of cash flow information:,,,\\n\\\"Cash paid for income taxes, net\\\",6549,1404,396\\nCash paid for interest,252,254,246\"\n}\n",
      "type": "registry:file",
      "target": "@components/viewers/sample-data/excel-splitting.json"
    }
  ],
  "categories": [
    "primitives"
  ],
  "type": "registry:block"
}