{"_id":"char-flow","_rev":"5-bf3a254cd4bb26436a644e94f73502c2","name":"char-flow","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.2":{"name":"char-flow","version":"0.1.2","keywords":["animation","text","license-plate","kenteken","web-component","custom-element","react","alphanumeric","diff"],"author":{"name":"scankenteken"},"license":"MIT","_id":"char-flow@0.1.2","maintainers":[{"name":"scan-kenteken","email":"mark@scankenteken.nl"}],"homepage":"https://github.com/scan-kenteken/char-flow#readme","bugs":{"url":"https://github.com/scan-kenteken/char-flow/issues"},"dist":{"shasum":"4e764a62fc0f114dbfba8b553a70d6e74c26cb13","tarball":"https://registry.npmjs.org/char-flow/-/char-flow-0.1.2.tgz","fileCount":13,"integrity":"sha512-qD+r3dA61WTIcHPmPnSad8OYKNIGRW10kdfFijhx2dl6iOHyACDw1TT8TDkq2iS90QL2zwNSxuyfOLE+v97Xjg==","signatures":[{"sig":"MEQCICDa+WoFxszooVmpZWc7MT6ez4NpCONLbGLxCIUVuEUYAiBnE0sx4hea9rRcgvlaTJnV41th45c0ksfHVMHJn9nHfQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":169527},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./element":{"types":"./dist/element.d.ts","import":"./dist/element.js"}},"gitHead":"7308de7c57bc3f67948f367a6ece5c2d2cd854b7","scripts":{"dev":"tsup --watch","demo":"npm run build && cp dist/element.js demo/element.js && npx --yes serve . -p 3000","build":"tsup","clean":"node -e \"import('node:fs').then(fs => fs.rmSync('dist', { recursive: true, force: true }))\"","prepack":"npm run typecheck && npm run build","typecheck":"tsc --noEmit","capture-demo":"node scripts/capture-demo.mjs"},"_npmUser":{"name":"scan-kenteken","email":"mark@scankenteken.nl"},"repository":{"url":"git+https://github.com/scan-kenteken/char-flow.git","type":"git"},"_npmVersion":"11.12.1","description":"CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs","directories":{},"sideEffects":true,"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","react":"^19.1.0","typescript":"^5.8.3","@types/react":"^19.1.8","puppeteer-core":"^25.1.0"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/char-flow_0.1.2_1781728163546_0.7935522512448856","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"char-flow","version":"0.1.3","keywords":["animation","text","license-plate","kenteken","web-component","custom-element","react","alphanumeric","diff"],"author":{"name":"scankenteken"},"license":"MIT","_id":"char-flow@0.1.3","maintainers":[{"name":"scan-kenteken","email":"mark@scankenteken.nl"}],"homepage":"https://github.com/scan-kenteken/char-flow#readme","bugs":{"url":"https://github.com/scan-kenteken/char-flow/issues"},"dist":{"shasum":"53c31b7dd34d8a90f4c73a9ae1fbc81af270d950","tarball":"https://registry.npmjs.org/char-flow/-/char-flow-0.1.3.tgz","fileCount":13,"integrity":"sha512-KBiC0KNsvZRQG2Q5kARDHje3KCFLWMIRu35uVt/5lVEOrw+gg+1XkF6NXTMBAEoawrNPMlC3U6wMSGzi60vmWw==","signatures":[{"sig":"MEUCIQCI930QYQbSbFGYpxBEY1t1T9d95f10o1PuaX0sTFvYgwIgWTfbcXTMqEsxTqJuSt2cePxjJaXYpNoPvJZMtHyrAwY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/char-flow@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":169527},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./element":{"types":"./dist/element.d.ts","import":"./dist/element.js"}},"gitHead":"64d9db06b5c7eeb35972124f11fe190b563bce23","scripts":{"dev":"tsup --watch","demo":"npm run build && cp dist/element.js demo/element.js && npx --yes serve . -p 3000","build":"tsup","clean":"node -e \"import('node:fs').then(fs => fs.rmSync('dist', { recursive: true, force: true }))\"","prepack":"npm run typecheck && npm run build","typecheck":"tsc --noEmit","capture-demo":"node scripts/capture-demo.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ab1e1318-bb3c-48de-832c-f4c7c7cd273c"}},"repository":{"url":"git+https://github.com/scan-kenteken/char-flow.git","type":"git"},"_npmVersion":"11.13.0","description":"CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs","directories":{},"sideEffects":true,"_nodeVersion":"24.16.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","react":"^19.1.0","typescript":"^5.8.3","@types/react":"^19.1.8","puppeteer-core":"^25.1.0"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/char-flow_0.1.3_1781859974604_0.16183469265206418","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"char-flow","version":"0.1.4","keywords":["animation","text","license-plate","kenteken","web-component","custom-element","react","alphanumeric","diff"],"author":{"name":"scankenteken"},"license":"MIT","_id":"char-flow@0.1.4","maintainers":[{"name":"scan-kenteken","email":"mark@scankenteken.nl"}],"homepage":"https://github.com/scan-kenteken/char-flow#readme","bugs":{"url":"https://github.com/scan-kenteken/char-flow/issues"},"dist":{"shasum":"209aeaeccad7d27fc402d0e5b5cf3d5e5d076b63","tarball":"https://registry.npmjs.org/char-flow/-/char-flow-0.1.4.tgz","fileCount":13,"integrity":"sha512-pvfVo3080bWzL9sjuxLcgk56xLxhhMtdtA40tSB1yOj097zWXkeWSbtYg4LhE22s8ppA4GuS5mKGuG5jBwInag==","signatures":[{"sig":"MEQCID9kP/nu2+ePztmtMB3qxpd6MrReXxZkazvSM4/56etlAiAYuT7FT4pp/VCSrnCrp4ZBHboyxwvwW9un6c9jn5/znw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/char-flow@0.1.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":173965},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./element":{"types":"./dist/element.d.ts","import":"./dist/element.js"}},"gitHead":"ba664ed57d652e82a4637eef4d518aa55f0c57d6","scripts":{"dev":"tsup --watch","demo":"npm run build && cp dist/element.js demo/element.js && npx --yes serve . -p 3000","build":"tsup","clean":"node -e \"import('node:fs').then(fs => fs.rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","capture-demo":"node scripts/capture-demo.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ab1e1318-bb3c-48de-832c-f4c7c7cd273c"}},"repository":{"url":"git+https://github.com/scan-kenteken/char-flow.git","type":"git"},"_npmVersion":"11.13.0","description":"CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs","directories":{},"sideEffects":true,"_nodeVersion":"24.17.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","react":"^19.1.0","typescript":"^5.8.3","@types/react":"^19.1.8","puppeteer-core":"^25.1.0"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/char-flow_0.1.4_1782741086819_0.4490526973796447","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"char-flow","version":"0.1.5","keywords":["animation","text","license-plate","kenteken","web-component","custom-element","react","alphanumeric","diff"],"author":{"name":"scankenteken"},"license":"MIT","_id":"char-flow@0.1.5","maintainers":[{"name":"scan-kenteken","email":"mark@scankenteken.nl"}],"homepage":"https://github.com/scan-kenteken/char-flow#readme","bugs":{"url":"https://github.com/scan-kenteken/char-flow/issues"},"dist":{"shasum":"160b99fbe4dc593af5c3866423d0cba506152efe","tarball":"https://registry.npmjs.org/char-flow/-/char-flow-0.1.5.tgz","fileCount":13,"integrity":"sha512-6mICSyQJnO69M0ULO/wKFhDV4OfknwVkCbrI0vrBxOjAzZMMwR4sCLlooOp9oxo0/pOwdRlcR4MlMWrqtEA3Og==","signatures":[{"sig":"MEUCIQCExvAFi9aLhzbQ2H+vfXKf8YE+ChlPSnE5szWArZDnVAIgfA9ZSoGTTATHrVS7E7SxdzYcf2oNd2c5pxbiOtPqZEo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/char-flow@0.1.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":181398},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./element":{"types":"./dist/element.d.ts","import":"./dist/element.js"}},"gitHead":"48a59738de7e4cd244e410c924d9191765375234","scripts":{"dev":"tsup --watch","demo":"npm run build && cp dist/element.js demo/element.js && npx --yes serve . -p 3000","build":"tsup","clean":"node -e \"import('node:fs').then(fs => fs.rmSync('dist', { recursive: true, force: true }))\"","test:roll":"npm run build && npx --yes tsx scripts/test-roll.ts","typecheck":"tsc --noEmit","capture-demo":"node scripts/capture-demo.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ab1e1318-bb3c-48de-832c-f4c7c7cd273c"}},"repository":{"url":"git+https://github.com/scan-kenteken/char-flow.git","type":"git"},"_npmVersion":"11.13.0","description":"CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs","directories":{},"sideEffects":true,"_nodeVersion":"24.17.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","react":"^19.1.0","typescript":"^5.8.3","@types/react":"^19.1.8","puppeteer-core":"^25.1.0"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/char-flow_0.1.5_1782743350418_0.2727761314161097","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"char-flow","version":"0.1.6","description":"CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs","type":"module","license":"MIT","author":{"name":"scankenteken"},"repository":{"type":"git","url":"git+https://github.com/scan-kenteken/char-flow.git"},"bugs":{"url":"https://github.com/scan-kenteken/char-flow/issues"},"homepage":"https://github.com/scan-kenteken/char-flow#readme","keywords":["animation","text","license-plate","kenteken","web-component","custom-element","react","alphanumeric","diff"],"engines":{"node":">=18"},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./element":{"types":"./dist/element.d.ts","import":"./dist/element.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"}},"sideEffects":true,"scripts":{"clean":"node -e \"import('node:fs').then(fs => fs.rmSync('dist', { recursive: true, force: true }))\"","build":"tsup","demo":"npm run build && cp dist/element.js demo/element.js && npx --yes serve . -p 3000","dev":"tsup --watch","typecheck":"tsc --noEmit","test:roll":"npm run build && npx --yes tsx scripts/test-roll.ts","capture-demo":"node scripts/capture-demo.mjs"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"devDependencies":{"@types/react":"^19.1.8","puppeteer-core":"^25.1.0","react":"^19.1.0","tsup":"^8.5.0","typescript":"^5.8.3"},"gitHead":"ceec1516c524052c6bdc09a621eaaeba371bfc36","_id":"char-flow@0.1.6","_nodeVersion":"24.17.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-A0iCShavVjEPGdAwvP0pozI0igO+4STdvlJK+vcBdl9P4Pz6FP6u/42WO8swTLJiDM6Kw+iETWQxN6mCUmLhqQ==","shasum":"978630106247ffa388dae79f528cd75810661f54","tarball":"https://registry.npmjs.org/char-flow/-/char-flow-0.1.6.tgz","fileCount":13,"unpackedSize":181953,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/char-flow@0.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCSfKeyQklkyg42ukOtyXlE95dvOINwr4xcMLLLoJLoUwIhAJrgAzDt+Ivt/9Lno9kwRUH/OOengWxhgH2+4ZycRxOm"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ab1e1318-bb3c-48de-832c-f4c7c7cd273c"}},"directories":{},"maintainers":[{"name":"scan-kenteken","email":"mark@scankenteken.nl"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/char-flow_0.1.6_1782743652656_0.31561117953885587"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-17T20:29:23.467Z","modified":"2026-06-29T14:34:13.045Z","0.1.2":"2026-06-17T20:29:23.685Z","0.1.3":"2026-06-19T09:06:14.739Z","0.1.4":"2026-06-29T13:51:26.967Z","0.1.5":"2026-06-29T14:29:10.577Z","0.1.6":"2026-06-29T14:34:12.795Z"},"bugs":{"url":"https://github.com/scan-kenteken/char-flow/issues"},"author":{"name":"scankenteken"},"license":"MIT","homepage":"https://github.com/scan-kenteken/char-flow#readme","keywords":["animation","text","license-plate","kenteken","web-component","custom-element","react","alphanumeric","diff"],"repository":{"type":"git","url":"git+https://github.com/scan-kenteken/char-flow.git"},"description":"CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs","maintainers":[{"name":"scan-kenteken","email":"mark@scankenteken.nl"}],"readme":"# CharFlow\n\nLightweight animated alphanumeric text for license plates, codes, and flowing paragraphs.\n\nDigits and letters roll through their alphabet on change; inserts and deletes slide in and out. Built as a web component with an optional React wrapper.\n\n<p align=\"center\">\n  <img src=\"./assets/demo.gif\" alt=\"CharFlow demo: animated text and license plate\" width=\"720\" />\n</p>\n\n## Install\n\n```sh\nnpm install char-flow\n```\n\n## Web component\n\nImport the element entry to register `<char-flow>`:\n\n```html\n<script type=\"module\">\n  import 'char-flow/element'\n</script>\n\n<char-flow value=\"G-123-BB\" preset=\"plate\"></char-flow>\n```\n\nOr use the main entry (registers the element and re-exports helpers):\n\n```ts\nimport 'char-flow'\n```\n\n### Attributes\n\n| Attribute | Default | Description |\n|---|---|---|\n| `value` | `\"\"` | Text to display |\n| `preset` | `alnum` | `plate` (uppercase, tabular) or `alnum` |\n| `animated` | `true` | Set to `false` to disable motion |\n| `direction` | `auto` | `auto` picks the shortest wheel path, `forward` counts up, `backward` counts down |\n| `roll` | `auto` | `auto` matches path direction, `up` / `down` force the on-screen scroll (path still follows `direction`) |\n\nUse `direction` for which wheel route to take and `roll` for how it should look. A clock ticking forward with digits rolling down:\n\n```html\n<char-flow value=\"12:32\" direction=\"forward\" roll=\"down\"></char-flow>\n```\n\nAnimations respect `prefers-reduced-motion`.\n\n### Styling\n\nThe component uses shadow DOM. Target the host or the exposed `part`:\n\n```css\nchar-flow.plate {\n  font-size: 2.5rem;\n  font-weight: 700;\n  letter-spacing: 0.06em;\n}\n\nchar-flow::part(root) {\n  /* inner shell */\n}\n```\n\nTiming can be adjusted from JavaScript:\n\n```ts\nconst el = document.querySelector('char-flow')\nel.spinTiming = { duration: 520, easing: 'cubic-bezier(0.32, 0.72, 0, 1)' }\nel.slideTiming = { duration: 340 }\n```\n\n## React\n\nRegister the element first, then use the wrapper:\n\n```tsx\nimport 'char-flow/element'\nimport { CharFlow } from 'char-flow/react'\n\nexport function Plate({ value }: { value: string }) {\n  return <CharFlow value={value} preset=\"plate\" className=\"plate\" />\n}\n\nexport function Clock({ value }: { value: string }) {\n  return <CharFlow value={value} preset=\"alnum\" direction=\"forward\" roll=\"down\" />\n}\n```\n\nReact is an optional peer dependency (`>=18`).\n\n## Low-level API\n\nThe main entry also exports diffing, classification, and stack-planning helpers:\n\n```ts\nimport { diff, classify, planFor, applyRoll } from 'char-flow'\n\ndiff('ABC-100', 'ABC-9')\nclassify('G')\n\n// inspect or customise a digit roll before rendering\nconst plan = planFor(\n  { key: 'm', char: '3', anim: 'wheel-digit', fromChar: '2' },\n  'forward',\n  'down',\n)\n```\n\n## Demo\n\n```sh\nnpm run demo\n```\n\nOpens a local demo at `http://localhost:3000/demo/`.\n\n## Development\n\n```sh\nnpm install\nnpm run build\nnpm run typecheck\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}