{"_id":"@abmaelsouza/pretext-styled-renderer","_rev":"7-5cc134702df569ff7f2b5de12fb7341b","name":"@abmaelsouza/pretext-styled-renderer","dist-tags":{"latest":"1.0.2-build.2437134747"},"versions":{"1.0.1":{"name":"@abmaelsouza/pretext-styled-renderer","version":"1.0.1","_id":"@abmaelsouza/pretext-styled-renderer@1.0.1","maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"dist":{"shasum":"6787f4b1816979d81250ef9f4183087ed4e36eee","tarball":"https://registry.npmjs.org/@abmaelsouza/pretext-styled-renderer/-/pretext-styled-renderer-1.0.1.tgz","fileCount":8,"integrity":"sha512-kjeAIumW8+tbK5yFbeJlsrFmJ98OsMUoHoZui7nr/9algFEULH7drW0BEt6/qLPGnesPBS33vlHZt8Jvz8hbnA==","signatures":[{"sig":"MEYCIQD7sb3DzNuwQsqwUwbvPowkm0uCCaWc0HlW8P0PqE4R9gIhAK/x1NGpyAOMWkjHD/xtzATuZsMQoNTKWrHTNFzBpKeZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59626},"module":"fesm2022/abmaelsouza-pretext-styled-renderer.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/abmaelsouza-pretext-styled-renderer.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"107d33358e837f9fc80cd33aeb5ee3ee4c04181e","typings":"index.d.ts","_npmUser":{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"},"_npmVersion":"10.8.2","description":"This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.2.0.","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^19.2.0","@angular/common":"^19.2.0"},"_npmOperationalInternal":{"tmp":"tmp/pretext-styled-renderer_1.0.1_1775469009662_0.04917043044377367","host":"s3://npm-registry-packages-npm-production"}},"1.0.1-build.2431804797":{"name":"@abmaelsouza/pretext-styled-renderer","version":"1.0.1-build.2431804797","_id":"@abmaelsouza/pretext-styled-renderer@1.0.1-build.2431804797","maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"dist":{"shasum":"1cd22ea2c99b6a97f64f27d5f0fa97f7e4af9101","tarball":"https://registry.npmjs.org/@abmaelsouza/pretext-styled-renderer/-/pretext-styled-renderer-1.0.1-build.2431804797.tgz","fileCount":8,"integrity":"sha512-VoqKPj8pyA3QZPM2bjMOQTSrrSFZ5RRo6SeDDvyrnK2hpyUyfQIz5/srfYewOacG1tCcecjp6KG4IBKzMGaL3g==","signatures":[{"sig":"MEYCIQCgUWw2WwjLZFxolz1LWT3ckpEQbxGPYrk6QjO1WVvlcwIhAPkc6XD3/WO2JTAh/ODCmzSaS8nFGaBgVN9Fb5KSRBIu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61521},"module":"fesm2022/abmaelsouza-pretext-styled-renderer.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/abmaelsouza-pretext-styled-renderer.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"26730ae29fcb771027b5156f8e86651134388462","typings":"index.d.ts","_npmUser":{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"},"_npmVersion":"10.8.2","description":"A high-performance, rich-text rendering engine for Angular that performs layout calculations entirely outside the DOM. It provides pixel-perfect text wrapping, rich styling support, and a comprehensive Query API for inspecting layout metrics without relyi","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^19.2.0","@angular/common":"^19.2.0"},"_npmOperationalInternal":{"tmp":"tmp/pretext-styled-renderer_1.0.1-build.2431804797_1775469930034_0.4342733796264593","host":"s3://npm-registry-packages-npm-production"}},"1.0.1-build.2431817778":{"name":"@abmaelsouza/pretext-styled-renderer","version":"1.0.1-build.2431817778","_id":"@abmaelsouza/pretext-styled-renderer@1.0.1-build.2431817778","maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"dist":{"shasum":"7150e43c1635f524fe6ea5f79112aadc231aba17","tarball":"https://registry.npmjs.org/@abmaelsouza/pretext-styled-renderer/-/pretext-styled-renderer-1.0.1-build.2431817778.tgz","fileCount":8,"integrity":"sha512-KwFaqLdmqhNqEDonZPdasW0nzKbS7VQENmMbgJFzEm7T68/mE+k22EWaCMcbYbF5JLLCdOkiSWxkNv735bZI8g==","signatures":[{"sig":"MEUCIQCt1UCw8+xUqhB8mjY7yOT5k7DRjIert+DMCJ4blwZMMgIgDq5UsYnIuEEBzOkTohDqmCcAF+PTNQaPEYImZopD6sM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62485},"module":"fesm2022/abmaelsouza-pretext-styled-renderer.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/abmaelsouza-pretext-styled-renderer.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"9f8830ed890b075bfd3d86eed60ef63d2bc06bae","typings":"index.d.ts","_npmUser":{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"},"_npmVersion":"10.8.2","description":"A high-performance, rich-text rendering engine for Angular that performs layout calculations entirely outside the DOM. It provides pixel-perfect text wrapping, rich styling support, and a comprehensive Query API for inspecting layout metrics without relyi","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^19.2.0","@angular/common":"^19.2.0"},"_npmOperationalInternal":{"tmp":"tmp/pretext-styled-renderer_1.0.1-build.2431817778_1775470224134_0.6741185092066395","host":"s3://npm-registry-packages-npm-production"}},"1.0.1-build.2431820880":{"name":"@abmaelsouza/pretext-styled-renderer","version":"1.0.1-build.2431820880","_id":"@abmaelsouza/pretext-styled-renderer@1.0.1-build.2431820880","maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"dist":{"shasum":"29089c1cb945c7f5588bd355aee006eda349ebc9","tarball":"https://registry.npmjs.org/@abmaelsouza/pretext-styled-renderer/-/pretext-styled-renderer-1.0.1-build.2431820880.tgz","fileCount":8,"integrity":"sha512-talSccz9KvBRb2Y7LcfGa/7ijcvcsGzSY6WVF8tr06YOHoVNeyiJpSAH/sviawQf623CRwp+p5I+xGHXIKVE3w==","signatures":[{"sig":"MEQCIH/60AnBaQoWEmZ6jibaFip7Y4DwcaRviHJFXJyDcayvAiB7oKRp3z/JmOxVPqDtqGkT+gWvODHMq1+CFnKcd0FPvw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62550},"module":"fesm2022/abmaelsouza-pretext-styled-renderer.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/abmaelsouza-pretext-styled-renderer.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"ff303fcd9975d1a4852e52bbad9faaeb2edeb089","typings":"index.d.ts","_npmUser":{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"},"_npmVersion":"10.8.2","description":"A high-performance, **framework-agnostic** rich-text rendering engine for TypeScript. It performs layout calculations entirely outside the DOM, making it compatible with any environment that provides a DOM (React, Vue, Svelte, Angular, or Vanilla JS). It ","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/pretext-styled-renderer_1.0.1-build.2431820880_1775470356411_0.5513230299670233","host":"s3://npm-registry-packages-npm-production"}},"1.0.2-build.2431829306":{"name":"@abmaelsouza/pretext-styled-renderer","version":"1.0.2-build.2431829306","license":"MIT","_id":"@abmaelsouza/pretext-styled-renderer@1.0.2-build.2431829306","maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"dist":{"shasum":"16cc05fb044e2d77ac6af6b5e6d2f28ce423b669","tarball":"https://registry.npmjs.org/@abmaelsouza/pretext-styled-renderer/-/pretext-styled-renderer-1.0.2-build.2431829306.tgz","fileCount":9,"integrity":"sha512-qBt20kP2Bn15UqfPIZ/1KoEdwf17yE4EAF/ipKeIuSAtD2tfV0rYGUdWZVYeLbQCTedwd0i2z6WojQOONss2zQ==","signatures":[{"sig":"MEUCIQCcWuDvO/3jgkZhx68gFY2ZCiQZmOhPQyq/Jv/4Hp+XrgIgaWHoKJjLURMnylhMCpMfxRl+O/KCK5cYJnPGrC05O1Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63650},"module":"fesm2022/abmaelsouza-pretext-styled-renderer.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/abmaelsouza-pretext-styled-renderer.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"5896b1685b4adc1845ae36228184d032e7bbd60b","typings":"index.d.ts","_npmUser":{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"},"_npmVersion":"10.8.2","description":"A high-performance, **framework-agnostic** rich-text rendering engine for TypeScript. It performs layout calculations entirely outside the DOM, making it compatible with any environment that provides a DOM (React, Vue, Svelte, Angular, or Vanilla JS). It ","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/pretext-styled-renderer_1.0.2-build.2431829306_1775470669993_0.8376115902775765","host":"s3://npm-registry-packages-npm-production"}},"1.0.2-build.2437127528":{"name":"@abmaelsouza/pretext-styled-renderer","version":"1.0.2-build.2437127528","keywords":["text layout","text measurement","text wrapping","line breaking","hyphenation","rich text","text renderer","layout engine","typography","canvas text","headless","text metrics","hit testing","custom editor","responsive text","typescript","javascript"],"license":"MIT","_id":"@abmaelsouza/pretext-styled-renderer@1.0.2-build.2437127528","maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"dist":{"shasum":"16e7540cd31edbc3aa892fd28916fe2bfa55aaaf","tarball":"https://registry.npmjs.org/@abmaelsouza/pretext-styled-renderer/-/pretext-styled-renderer-1.0.2-build.2437127528.tgz","fileCount":9,"integrity":"sha512-wBuMb3XiQ0teb57HltfVtmKT9qcawhS9Qa/WPM6domqZGtX17btDu+SU5ZHG74KcIGf1JXTXPUcV2WlhJPOHcw==","signatures":[{"sig":"MEUCIQCdZanaDciqetKxnTokRW1VSZRAJRxw23kMYZjs6xrH/AIgeVHgBCCjlUc/JEGZDn7HzNf3/8EVfhPyDmuAZ6wQoG0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64191},"module":"fesm2022/abmaelsouza-pretext-styled-renderer.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/abmaelsouza-pretext-styled-renderer.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"c49ce60610389b63e44147f41778203826b138b0","typings":"index.d.ts","_npmUser":{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"},"_npmVersion":"10.8.2","description":"Headless text layout engine for TypeScript and JavaScript. Supports text measurement, line breaking, hyphenation, and rich text rendering without relying on the DOM.","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/pretext-styled-renderer_1.0.2-build.2437127528_1775645086472_0.715007462450125","host":"s3://npm-registry-packages-npm-production"}},"1.0.2-build.2437134747":{"name":"@abmaelsouza/pretext-styled-renderer","version":"1.0.2-build.2437134747","keywords":["text layout","text measurement","text wrapping","line breaking","hyphenation","rich text","text renderer","layout engine","typography","canvas text","headless","text metrics","hit testing","custom editor","responsive text","typescript","javascript"],"description":"Headless text layout engine for TypeScript and JavaScript. Supports text measurement, line breaking, hyphenation, and rich text rendering without relying on the DOM.","license":"MIT","peerDependencies":{"@chenglou/pretext":"0.0.4"},"dependencies":{"tslib":"^2.3.0"},"sideEffects":false,"module":"fesm2022/abmaelsouza-pretext-styled-renderer.mjs","typings":"index.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./index.d.ts","default":"./fesm2022/abmaelsouza-pretext-styled-renderer.mjs"}},"_id":"@abmaelsouza/pretext-styled-renderer@1.0.2-build.2437134747","gitHead":"0bf9b9dd6028cb5a15eacc8309c105c6a20f6c33","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-FL818h3lbTjpNr7ovPwu+BwcWoQ455sWkJtdDXts8WHqKedCgCCJrgvlUIvxopN/BqQQ/rR2rGquvD5oaT3Psw==","shasum":"af3f7d948a0724cc53aa5ab01771eff16eebb6f3","tarball":"https://registry.npmjs.org/@abmaelsouza/pretext-styled-renderer/-/pretext-styled-renderer-1.0.2-build.2437134747.tgz","fileCount":9,"unpackedSize":64227,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIE8XjQR3XhBegfPT97uJwyiFozHsbhf67xgeQvY7g7PuAiB8Z8HiJ49796jCMPzOJ+GaWYRZDWV3/NAOU1NAFdyn5g=="}]},"_npmUser":{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"},"directories":{},"maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pretext-styled-renderer_1.0.2-build.2437134747_1775645281185_0.4545875978850611"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-06T09:50:09.560Z","modified":"2026-04-08T10:48:01.444Z","1.0.1":"2026-04-06T09:50:09.802Z","1.0.1-build.2431804797":"2026-04-06T10:05:30.175Z","1.0.1-build.2431817778":"2026-04-06T10:10:24.295Z","1.0.1-build.2431820880":"2026-04-06T10:12:36.576Z","1.0.2-build.2431829306":"2026-04-06T10:17:50.131Z","1.0.2-build.2437127528":"2026-04-08T10:44:46.627Z","1.0.2-build.2437134747":"2026-04-08T10:48:01.338Z"},"license":"MIT","keywords":["text layout","text measurement","text wrapping","line breaking","hyphenation","rich text","text renderer","layout engine","typography","canvas text","headless","text metrics","hit testing","custom editor","responsive text","typescript","javascript"],"description":"Headless text layout engine for TypeScript and JavaScript. Supports text measurement, line breaking, hyphenation, and rich text rendering without relying on the DOM.","maintainers":[{"name":"abmaelsouza","email":"abmaelpsouza@gmail.com"}],"readme":"# @abmaelsouza/pretext-styled-renderer\n\nA high-performance, **framework-agnostic** rich-text rendering engine for TypeScript. It performs layout calculations entirely outside the DOM, making it compatible with any environment that provides a DOM (React, Vue, Svelte, Angular, or Vanilla JS). It provides pixel-perfect text wrapping, rich styling support, and a comprehensive Query API for inspecting layout metrics without relying on `getBoundingClientRect`.\n\n## Features\n\n- 🚀 **Zero-DOM Layout**: Calculates line breaks and fragment positions using a canvas-like measurement engine.\n- 🎨 **Rich Styling per Span**: Apply unique fonts, weights, colors, and backgrounds to any text fragment.\n- 📏 **Programmatic Metrics**: Query bounding boxes for the total block, individual lines, or text fragments.\n- ⌨️ **Hit-Testing**: Determine which line or fragment exists at a specific coordinate.\n- 🔠 **Smart Hyphenation**: Built-in syllable-aware hyphenation logic.\n- ⚡ **Performance**: Highly optimized for dynamic layouts and frequent resizing.\n\n---\n\n## Installation\n\n```bash\nnpm install @abmaelsouza/pretext-styled-renderer\n```\n\n---\n\n## Quick Start\n\n### 1. Initialize the Engine\n\n```typescript\nimport { PretextStyledEngine, type StyledSpan } from '@abmaelsouza/pretext-styled-renderer';\n\nconst engine = new PretextStyledEngine({\n  outerPaddingPx: 20,\n  defaultStyle: {\n    fontSize: 18,\n    fontFamily: 'system-ui, sans-serif',\n    lineHeight: 1.4,\n    color: '#1e293b'\n  }\n});\n```\n\n### 2. Define Styled Spans\n\n```typescript\nconst spans: StyledSpan[] = [\n  { text: 'Hello ', style: { fontWeight: 'bold', color: 'blue' } },\n  { text: 'World!', style: { fontStyle: 'italic', backgroundColor: '#f0f0f0' } }\n];\n```\n\n### 3. Calculate Layout & Sync to DOM\n\n```typescript\n// Perform the layout calculation (no DOM used here)\nengine.layout(spans, 400); // 400px width\n\n// Sync the results to a container element\nconst container = document.getElementById('text-container');\nengine.syncDom(container);\n```\n\n---\n\n## Responsive Layout (Handling Resizes)\n\nThe engine calculates layout based on a fixed width. To make the text responsive, you must recalibrate the layout and call `syncDom` whenever the container size changes.\n\n### Using ResizeObserver (Recommended)\nThis is the most efficient way to detect when the actual container element changes size.\n\n```typescript\nconst container = document.getElementById('text-container');\n\nconst observer = new ResizeObserver(entries => {\n  for (let entry of entries) {\n    const newWidth = entry.contentRect.width;\n    \n    // Recalculate and update the DOM\n    engine.layout(spans, newWidth);\n    engine.syncDom(container);\n  }\n});\n\nobserver.observe(container);\n```\n\n### Using Window Resize\nFor simpler layouts, you can listen to the window's `resize` event.\n\n```typescript\nwindow.addEventListener('resize', () => {\n  const newWidth = container.clientWidth;\n  engine.layout(spans, newWidth);\n  engine.syncDom(container);\n});\n```\n\n---\n\n## The Query API (Layout Metrics)\n\nThe engine provides a set of methods to inspect the rendered content programmatically. This is useful for drawing overlays, implementing custom selections, or hit-testing.\n\n| Method | Description |\n| :--- | :--- |\n| `getTotalRect()` | Returns the `{x, y, width, height}` of the entire text block. |\n| `getLineRect(row)` | Returns the bounding box of a specific line index. |\n| `getFragmentRects(row)` | Returns an array of bounding boxes for every styled fragment in a line. |\n| `getLineAtHeight(y)` | Returns the index of the line located at a specific vertical offset. |\n| `getLineWidths()` | Returns an array of widths for every rendered line. |\n| `getLineText(row)` | Returns the raw string content of a specific line. |\n| `getFullText()` | Returns the entire concatenated text content. |\n\n---\n\n## Styling Options (`TextStyle`)\n\nEvery `StyledSpan` can be customized with the following properties:\n\n- `fontSize`: Number (px) or String (e.g., `'18px'`)\n- `fontFamily`: Font family stack (e.g., `'Inter, sans-serif'`)\n- `fontWeight`: `'normal'`, `'bold'`, or numeric values like `600`.\n- `fontStyle`: `'normal'`, `'italic'`, or `'oblique'`.\n- `lineHeight`: Multiplier (e.g., `1.5`) or pixel value.\n- `color`: CSS color string.\n- `backgroundColor`: CSS background-color string.\n- `letterSpacing`: CSS-like letter-spacing (e.g., `'0.5px'`).\n- `textAlign`: `'left'`, `'center'`, `'right'`.\n- `textDecoration`: `'none'`, `'underline'`, `'line-through'`.\n- `opacity`: Number between `0` and `1`.\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}