{"_id":"@cujuju/solidjs-pill-number-picker","_rev":"4-d8f57aed8e88bb0ebc8609ae428ee6fc","name":"@cujuju/solidjs-pill-number-picker","dist-tags":{"latest":"0.5.1"},"versions":{"0.1.0":{"name":"@cujuju/solidjs-pill-number-picker","version":"0.1.0","keywords":["solidjs","number-picker","stepper","spinbutton","input"],"author":{"name":"Cujuju"},"license":"MIT","_id":"@cujuju/solidjs-pill-number-picker@0.1.0","maintainers":[{"name":"cujuju","email":"cujuju@pm.me"}],"homepage":"https://github.com/Cujuju/solidjs-toolkit/tree/main/packages/pill-number-picker","bugs":{"url":"https://github.com/Cujuju/solidjs-toolkit/issues"},"dist":{"shasum":"517481392f13e8b3e64c8ca9bb8dd027cc21afdd","tarball":"https://registry.npmjs.org/@cujuju/solidjs-pill-number-picker/-/solidjs-pill-number-picker-0.1.0.tgz","fileCount":17,"integrity":"sha512-UTgEHLIb5pYozY+1T3jnb9+WFvBvJCUjXjA45HSJG/Q/kOFU5UTBirSlpUGUIC/zQ905On9G6/FvUstqExiGVw==","signatures":[{"sig":"MEUCIQD1La6y7cyiMeI9SdbWhBOzFSaTIUSeVV3ZjoQon37BtgIgJ1CNNDsJHXa2F8DmaOtHkYoCPhXRk7wo0p8ISQVIlek=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":96515},"main":"./dist/index.js","type":"module","_from":"file:cujuju-solidjs-pill-number-picker-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"solid":"./src/index.ts","types":"./dist/index.d.ts","import":"./dist/index.js"},"./styles.css":"./src/styles.css"},"scripts":{"test":"vitest run","build":"vite build","test:watch":"vitest"},"_npmUser":{"name":"cujuju","email":"cujuju@pm.me"},"_resolved":"C:\\Users\\shawn\\AppData\\Local\\Temp\\f726e222f803e7517e283fc1d2f5d0cf\\cujuju-solidjs-pill-number-picker-0.1.0.tgz","_integrity":"sha512-UTgEHLIb5pYozY+1T3jnb9+WFvBvJCUjXjA45HSJG/Q/kOFU5UTBirSlpUGUIC/zQ905On9G6/FvUstqExiGVw==","repository":{"url":"git+https://github.com/Cujuju/solidjs-toolkit.git","type":"git","directory":"packages/pill-number-picker"},"_npmVersion":"11.12.1","description":"Compact number stepper for SolidJS — 8 layouts, auto-repeat with acceleration, full spinbutton a11y, RTL-ready.","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"25.8.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4"},"peerDependencies":{"solid-js":">=1.7.0"},"_npmOperationalInternal":{"tmp":"tmp/solidjs-pill-number-picker_0.1.0_1777341462094_0.6882352633656439","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@cujuju/solidjs-pill-number-picker","version":"0.3.0","keywords":["solidjs","number-picker","stepper","spinbutton","input"],"author":{"name":"Cujuju"},"license":"MIT","_id":"@cujuju/solidjs-pill-number-picker@0.3.0","maintainers":[{"name":"cujuju","email":"cujuju@pm.me"}],"homepage":"https://github.com/Cujuju/solidjs-toolkit/tree/main/packages/pill-number-picker","bugs":{"url":"https://github.com/Cujuju/solidjs-toolkit/issues"},"dist":{"shasum":"34a054ee98615491ec8db71e8a76b3c3e5e28255","tarball":"https://registry.npmjs.org/@cujuju/solidjs-pill-number-picker/-/solidjs-pill-number-picker-0.3.0.tgz","fileCount":22,"integrity":"sha512-jMCBNUrlyCxc47/ogxZYpJ0wQM4HlsnRnw2zIV6TvRJ893kLcvi72CmIx+b0U0ofQCeogjR9yeLXvM/fs9RyLg==","signatures":[{"sig":"MEYCIQC6K1sP313I+T22B994BjHw2P55XDjruj0hq08vD8/6zgIhAMfR2FyPJAZPRfCut1mlNndr7NRy7nv8rK8WUxUh/s2i","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":206576},"main":"./dist/index.js","type":"module","_from":"file:cujuju-solidjs-pill-number-picker-0.3.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"solid":"./src/index.ts","types":"./dist/index.d.ts","import":"./dist/index.js"},"./styles.css":"./src/styles.css"},"scripts":{"test":"vitest run","build":"vite build","test:watch":"vitest"},"_npmUser":{"name":"cujuju","email":"cujuju@pm.me"},"_resolved":"/tmp/ca8df98fd0ee9ebf534685bdbc90195a/cujuju-solidjs-pill-number-picker-0.3.0.tgz","_integrity":"sha512-jMCBNUrlyCxc47/ogxZYpJ0wQM4HlsnRnw2zIV6TvRJ893kLcvi72CmIx+b0U0ofQCeogjR9yeLXvM/fs9RyLg==","repository":{"url":"git+https://github.com/Cujuju/solidjs-toolkit.git","type":"git","directory":"packages/pill-number-picker"},"_npmVersion":"12.0.1","description":"Compact number stepper for SolidJS — 8 layouts, optional collapse-to-value with a portalled pop-out editor, commit-on-change or commit-on-finish, auto-repeat with acceleration, full spinbutton a11y, RTL-ready.","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^24.0.0","vitest":"^3.2.4","vite-plugin-solid":"^2.11.12","@testing-library/jest-dom":"^6.9.1"},"peerDependencies":{"solid-js":">=1.7.0"},"_npmOperationalInternal":{"tmp":"tmp/solidjs-pill-number-picker_0.3.0_1784887075702_0.03349102381769642","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@cujuju/solidjs-pill-number-picker","version":"0.5.0","keywords":["solidjs","number-picker","stepper","spinbutton","input"],"author":"Cujuju","license":"MIT","_id":"@cujuju/solidjs-pill-number-picker@0.5.0","maintainers":[{"name":"cujuju","email":"cujuju@pm.me"}],"homepage":"https://github.com/Cujuju/solidjs-toolkit/tree/main/packages/pill-number-picker","bugs":"https://github.com/Cujuju/solidjs-toolkit/issues","dist":{"shasum":"201b2619ceefa0fe9743d0f43d67d662cc5eaa82","tarball":"https://registry.npmjs.org/@cujuju/solidjs-pill-number-picker/-/solidjs-pill-number-picker-0.5.0.tgz","fileCount":29,"integrity":"sha512-27yelf+Bhq3r0d9WCEINAPq8EBSJOUclwOYbl+fepneQ2ldTdLF9xytgLBF/XPh3H1KzGDBQ6mP6MtTnZ1hcpQ==","signatures":[{"sig":"MEUCIQCE5C5doQhAJYPNDOzNkvKXmsMwo9+jGGJ0o2G3wP//sgIgdVjsG3ULhYw+wSGaej6bJh70qYTjMVBNpz0+wHPedyU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDdVXHh2WPFpzGJYmGSx6hldGLcdNDD5clyOCMTFWvfvgIgOHmQDBmnjhxfqv4tGlKElrQN0lxmmDCXwmuO1Vz5/9c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":257482},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"solid":"./src/index.ts","types":"./dist/index.d.ts","import":"./dist/index.js"},"./style.css":"./dist/style.css","./styles.css":"./src/styles.css"},"scripts":{"test":"vitest run","build":"vite build","test:watch":"vitest"},"_npmUser":{"name":"cujuju","email":"cujuju@pm.me"},"repository":{"url":"https://github.com/Cujuju/solidjs-toolkit.git","type":"git","directory":"packages/pill-number-picker"},"description":"Compact number stepper for SolidJS — 8 layouts, optional collapse-to-value with a portalled pop-out editor, commit-on-change or commit-on-finish, auto-repeat with acceleration, full spinbutton a11y, RTL-ready.","directories":{},"sideEffects":["**/*.css","./src/index.ts","./dist/index.js"],"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^24.0.0","vitest":"^3.2.4","vite-plugin-solid":"^2.11.12","@cujuju/solidjs-hooks":"^2.0.0","@testing-library/jest-dom":"^6.9.1"},"peerDependencies":{"solid-js":">=1.7.0","@cujuju/solidjs-hooks":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/solidjs-pill-number-picker_0.5.0_1791059627110_0.7412379170674088","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"_id":"@cujuju/solidjs-pill-number-picker@0.5.1","bugs":"https://github.com/Cujuju/solidjs-toolkit/issues","dist":{"shasum":"0c2f1e64f20b2bcd204940e562dfed064bddecbf","tarball":"https://registry.npmjs.org/@cujuju/solidjs-pill-number-picker/-/solidjs-pill-number-picker-0.5.1.tgz","fileCount":29,"integrity":"sha512-bVp2S6EiXlOtjGLaAYccmx8d6Kq3Pe4dGSjJMytnhIjoxacqQGGbnTKt64kSAQhlWzLlfqzsaSAArbtNsi7CkA==","signatures":[{"sig":"MEUCIQDntR4VAqY7JCQ9QHFiSHvznT1tn2lxY/z49jC4Z0jnsAIgD5T2kuLFccd/qSypOMyH188iBO9kKAa/OT+pVIVFE9A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDdUvgbVMECwe0JJFootvtIqnqErNxvWYZLK22VEtz4lgIgMsz3GT3YL/qWVlGd0nThy5Mc19bJELi6g6Ul2zdzO0E="}],"unpackedSize":257482},"main":"./dist/index.js","name":"@cujuju/solidjs-pill-number-picker","type":"module","types":"./dist/index.d.ts","author":"Cujuju","module":"./dist/index.js","exports":{".":{"solid":"./src/index.ts","types":"./dist/index.d.ts","import":"./dist/index.js"},"./style.css":"./dist/style.css","./styles.css":"./src/styles.css"},"license":"MIT","scripts":{"test":"vitest run","build":"vite build","test:watch":"vitest"},"version":"0.5.1","_npmUser":{"name":"cujuju","email":"cujuju@pm.me"},"homepage":"https://github.com/Cujuju/solidjs-toolkit/tree/main/packages/pill-number-picker","keywords":["solidjs","number-picker","stepper","spinbutton","input"],"repository":{"url":"https://github.com/Cujuju/solidjs-toolkit.git","type":"git","directory":"packages/pill-number-picker"},"description":"Compact number stepper for SolidJS — 8 layouts, optional collapse-to-value with a portalled pop-out editor, commit-on-change or commit-on-finish, auto-repeat with acceleration, full spinbutton a11y, RTL-ready.","directories":{},"maintainers":[{"name":"cujuju","email":"cujuju@pm.me"}],"sideEffects":["**/*.css","./src/index.ts","./dist/index.js"],"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^24.0.0","vitest":"^3.2.4","vite-plugin-solid":"^2.11.12","@cujuju/solidjs-hooks":"^2.1.0","@testing-library/jest-dom":"^6.9.1"},"peerDependencies":{"solid-js":">=1.7.0","@cujuju/solidjs-hooks":"^2.1.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/solidjs-pill-number-picker_0.5.1_1791060341331_0.6599499178804511"}}},"time":{"created":"2026-04-28T01:57:42.008Z","modified":"2026-10-03T20:45:41.567Z","0.1.0":"2026-04-28T01:57:42.226Z","0.3.0":"2026-07-24T09:57:55.830Z","0.5.0":"2026-10-03T20:33:47.202Z","0.5.1":"2026-10-03T20:45:41.410Z"},"bugs":"https://github.com/Cujuju/solidjs-toolkit/issues","author":"Cujuju","license":"MIT","homepage":"https://github.com/Cujuju/solidjs-toolkit/tree/main/packages/pill-number-picker","keywords":["solidjs","number-picker","stepper","spinbutton","input"],"repository":{"url":"https://github.com/Cujuju/solidjs-toolkit.git","type":"git","directory":"packages/pill-number-picker"},"description":"Compact number stepper for SolidJS — 8 layouts, optional collapse-to-value with a portalled pop-out editor, commit-on-change or commit-on-finish, auto-repeat with acceleration, full spinbutton a11y, RTL-ready.","maintainers":[{"name":"cujuju","email":"cujuju@pm.me"}],"readme":"# @cujuju/solidjs-pill-number-picker\n\nCompact number stepper for SolidJS. 8 layouts (horizontal + vertical). Optional collapse-to-value with a portalled pop-out. Auto-repeat with optional acceleration. Full spinbutton a11y. RTL-ready via CSS logical properties.\n\n## Install\n\n```\npnpm add @cujuju/solidjs-pill-number-picker\n```\n\nStylesheet auto-imports; or import `@cujuju/solidjs-pill-number-picker/styles.css` manually.\n\n## Usage\n\n```tsx\nimport { PillNumberPicker } from '@cujuju/solidjs-pill-number-picker';\n\nconst [qty, setQty] = createSignal(1);\n\n<PillNumberPicker\n  value={qty()}\n  onChange={setQty}\n  min={1}\n  max={10}\n  ariaLabel=\"Quantity\"\n/>\n```\n\n## API (highlights)\n\n| Prop | Default | Description |\n|---|---|---|\n| `value` | (required) | Controlled current value. |\n| `onChange(v)` | (required) | Called on any change. |\n| `min`, `max`, `step` | `1`, `100`, `1` | Range + step size. `step` may be non-integer (e.g., `0.5`, `0.01`). |\n| `precision` | (inferred from `step`) | Decimal places for parsing, step rounding, and display. Auto-inferred from `step` (so `step={0.5}` gives precision 1). Set explicitly to override — e.g. `step={1}, precision={2}` for integer steps with two-decimal display ('5.00'). Set to 0 to force integer mode regardless of step. |\n| `size` | `'md'` | `'xs'` / `'sm'` / `'md'`. |\n| `width`, `height`, `buttonWidth`, `fontSize` | (preset) | Raw overrides. |\n| `layout` | `'value-inc-dec'` | See layout table below. |\n| `collapsible` | `false` | Collapse to the value alone; reveal the buttons in a pop-out on demand. See below. |\n| `open`, `onOpenChange` | (uncontrolled) | Controlled pop-out state. Omit `open` to let the component own it. |\n| `popoutGap` | `4` | px between the collapsed value and the pop-out panel. |\n| `commit` | `'change'` | `'change'` publishes every step via `onChange`. `'finish'` steps a local draft and publishes only on confirmation. See below. |\n| `onCommit(v)` | — | The value was CONFIRMED — Enter, or clicking the pill again to close the editor. |\n| `onCancel(v)` | — | The session was ABANDONED — Escape, or an outside press. Receives the value the picker is left holding. |\n| `revertOnCancel` | `true` | Cancel restores the value the session started with. |\n| `editable` | `true` | Click value to edit inline. On a **collapsed** picker, opening the editor focuses and selects the field. |\n| `suffix` | — | Label appended after the value (e.g., `\"px\"`). |\n| `zeroLabel` | — | Display text when value is 0 (e.g., `\"∞\"`). |\n| `displayValue(v)` | — | Format the displayed value. |\n| `incrementIcon`, `decrementIcon` | `+`, `−` | JSX content for the buttons. |\n| `resetTo` | — | Adds a flush reset segment (`↺`) as the row's last member; clicking it sets this value through the normal publish channel. Disabled while the value already equals it. Sugar over `segments`. |\n| `resetIcon`, `resetLabel` | `'↺'`, `'Reset'` | Reset segment glyph + aria-label. |\n| `segments` | — | Custom segments joining the items row — see below. |\n| `showRange`, `rangeFormat` | `false` | Show `\"3 / 100\"`-style range. |\n| `invertScroll` | `false` | Wheel-up decrements instead of increments. |\n| `disableWheel` | `false` | No mouse-wheel handling. |\n| `requireFocus` | `false` | Wheel only works when focus is inside the picker (value cell, buttons, pop-out) — prevents scroll-trap in scrollable containers. |\n| `autoRepeatDelay` | `400` | ms before held +/− starts repeating. |\n| `autoRepeatInterval` | `60` | ms between repeats. |\n| `autoRepeatAcceleration` | `false` | Interval halves every 1.5s held, floor 15ms. |\n| `ariaLabel` | — | Screen-reader name for the picker. |\n| `incrementLabel`, `decrementLabel` | `'Increase'`, `'Decrease'` | Button labels (i18n). |\n| `disabled` | `false` | Non-interactive. |\n\n## Layouts\n\n| `layout` | Visual |\n|---|---|\n| `'value-inc-dec'` (default) | `[value][+][−]` |\n| `'value-dec-inc'` | `[value][−][+]` |\n| `'inc-value-dec'` | `[+][value][−]` |\n| `'dec-value-inc'` | `[−][value][+]` |\n| `'inc-dec-value'` | `[+][−][value]` |\n| `'dec-inc-value'` | `[−][+][value]` |\n| `'v-inc-value-dec'` | `[+] / [value] / [−]` (stacked) |\n| `'v-dec-value-inc'` | `[−] / [value] / [+]` (stacked) |\n\n## Collapse (`collapsible`)\n\nThe picker's chrome is most of its width. In a dense row — a table cell, an order leg, a rail — that chrome is paid for on every row and used on almost none. `collapsible` makes the resting state **the number alone**; the `+`/`−` appear only when you ask for them.\n\n```tsx\n<PillNumberPicker collapsible value={qty()} onChange={setQty} min={1} max={100} />\n```\n\n- **Collapsed**, the value cell hugs its digits (`max-content`, with the reserved width as a floor) — it can never truncate the number, however large it grows. It is still a full spinbutton: the wheel and the arrow keys step it *without* expanding, so the common case never opens the pop-out at all.\n- **Click** (or Enter / Space) expands. The panel renders through a `<Portal>` and is positioned in viewport coordinates — so it is **not clipped** by an ancestor with `overflow: hidden` or `overflow-y: auto`, which is what a plain absolutely-positioned expansion would die to in exactly the dense layouts this feature is for.\n- It opens **above** the anchor by preference (a panel below covers the *next* row — usually the next thing the user wants), flipping below only when there isn't room, and clamping into the viewport at the edges.\n- The anchor stays in flow while open, so expanding **never reflows the row**.\n- Dismiss: outside `pointerdown`, or `Escape` (which returns focus to the anchor).\n\nControlled, if you need to own it:\n\n```tsx\n<PillNumberPicker collapsible open={open()} onOpenChange={setOpen} value={qty()} onChange={setQty} />\n```\n\n## The editing session — `commit`, `onCommit`, `onCancel`\n\nClicking the collapsed pill opens the **editor**: the pop-out, with the value field focused and selected. That starts a *session*, which ends one of two ways:\n\n| | Gesture |\n|---|---|\n| **Commit** | `Enter`, or clicking the pill again to close it |\n| **Cancel** | `Escape`, or a pointerdown outside the pop-out |\n\n`commit` decides **when the value is published**:\n\n- **`'change'` (default)** — every step publishes immediately via `onChange`, exactly as the picker has always behaved. `onCommit` / `onCancel` still fire, so a consumer can tell a *settled* value from one being scrubbed through.\n- **`'finish'`** — the pop-out steps a **local draft**. The display updates; `onChange` stays silent; the value is published once, on commit. For a consumer where every intermediate value costs something real — a request per tick, an order repriced on every keystroke — being told about values the user never chose isn't noise, it's wrong, and debouncing at the callsite doesn't fix it.\n\n```tsx\n<PillNumberPicker\n  collapsible\n  commit=\"finish\"\n  value={qty()}\n  onChange={setQty}                 // fires ONCE, on commit\n  onCommit={(v) => placeOrder(v)}   // the user settled on v\n  onCancel={() => {}}               // abandoned; value restored\n/>\n```\n\n**Cancel reverts** by default, and means the same thing in both modes. In `'finish'` that's free (the draft is dropped). In `'change'` the consumer has already *seen* the intermediate values, so the revert is published as a real `onChange(valueAtOpen)` — without that, \"cancel\" would mean *undo* in one mode and *keep* in the other. Opt out with `revertOnCancel={false}`.\n\n**The collapsed pill still steps in place.** Wheel and arrow keys on the resting pill open no session and publish immediately in both modes — there's nothing to confirm, and requiring a confirmation for a scroll gesture would tax the fastest path the control has.\n\n## Custom segments (`segments`)\n\nAny button can join the pill as a first-class row member — same flush 1px\nborders, positional corner rounding, size-preset dimensions and disabled\ntreatment as the built-in steppers. Segments are declared as **data**, not\npassed-in JSX, so the component stays the owner of button rendering and the\nediting-session semantics:\n\n```tsx\n<PillNumberPicker\n  value={qty()} onChange={setQty} min={1} max={500}\n  segments={[\n    { key: 'min', icon: '⤓', label: 'Set to minimum', position: 'start',\n      onSelect: (api) => api.setValue(1) },\n    { key: 'x2', icon: '×2', label: 'Double', width: 24,\n      disabled: (v) => v * 2 > 500,\n      onSelect: (api) => api.setValue(api.value * 2) },\n    { key: 'done', icon: '✓', label: 'Confirm',\n      onSelect: (api) => api.commit() },\n  ]}\n/>\n```\n\nRow order is `[start segments…][layout parts][end segments…][reset]` — a\n`'start'` segment becomes `:first-child` and picks up the start corners; the\nreset segment (when `resetTo` is set) stays outermost-last. Each segment\nrenders with `data-pos=\"seg-<key>\"`.\n\n`onSelect` receives a **`PnpSegmentApi`** bound to the picker's own channel:\n\n| Member | Behaviour |\n|---|---|\n| `value` | The value at click time (draft-aware inside a session). |\n| `setValue(v)` | Clamped/rounded, draft-synced, `excludeZero`-resolved; inside a `commit:'finish'` session it edits the draft and stays silent until the session commits. |\n| `commit()` | Ends an open editing session as a confirmation (no-op when none is open). |\n| `cancel()` | Ends an open editing session as a cancel (no-op when none is open). |\n\nBecause everything flows through the same channel a stepper uses, a segment can\nnever bypass the session: cancel still reverts a segment's edit, and `'finish'`\nmode still withholds `onChange` until confirmation.\n\n## A11y\n\n- Wrapper has `role=\"group\"`; value span has `role=\"spinbutton\"` with `aria-valuenow/min/max`.\n- Keyboard: ArrowUp/ArrowDown (±step), PageUp/PageDown (±step×10), Home/End (min/max), Enter commits edit, Escape cancels.\n- `:focus-visible` ring via `--pnp-focus-ring`.\n- RTL: CSS logical properties flip corners for `dir=\"rtl\"` layouts.\n\n## Theming\n\n```css\n:root {\n  --pnp-bg: #1e293b;\n  --pnp-border: #334155;\n  --pnp-text: #e2e8f0;\n  --pnp-text-muted: #94a3b8;\n  --pnp-suffix-color: #64748b;\n  --pnp-radius: 9999px;\n  --pnp-disabled-opacity: 0.3;\n  --pnp-focus-ring: 2px solid #6366f1;\n  --pnp-focus-ring-offset: 2px;\n\n  /* collapse / pop-out */\n  --pnp-popout-z: 1000;\n  --pnp-popout-pad: 0px;\n  --pnp-popout-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);\n}\n```\n\n## Future ideas (not shipped)\n\n- Live digit-filter on input (`filterInput?: 'numeric' | 'digits'`) — today, non-numeric keypresses sit in the draft and are discarded on commit.\n\n## License\n\nMIT\n","readmeFilename":""}