{"_id":"@asnewyla/radio","_rev":"2-93b3a78441d567c97b3eea3374beb2a0","name":"@asnewyla/radio","dist-tags":{"latest":"0.2.1"},"versions":{"0.2.0":{"name":"@asnewyla/radio","version":"0.2.0","keywords":["react","radio","form","styled","accessible"],"license":"MIT","_id":"@asnewyla/radio@0.2.0","maintainers":[{"name":"asnewyla","email":"asnewyla@gmail.com"}],"dist":{"shasum":"dc73eb1278fe21ca92da077c592f58dd0a02a641","tarball":"https://registry.npmjs.org/@asnewyla/radio/-/radio-0.2.0.tgz","fileCount":11,"integrity":"sha512-+eqrUK1fVerFSaPu0dUs5sJ0YoQZoxN4twerIbvN+TFMntAOCL9rJF0cMQ2fN0VvFGJHG0Ay/Y/UF+DiRu61hA==","signatures":[{"sig":"MEQCIEBPS7aKmYgF+n4Kyc5u8dBbUnZ4ywFYyjxmqbSIY1JCAiAyPghtuRJjdSspBW8zeLqh5ZA6I2JT0XKIjB8PqrS0rQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23713},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./styles.css":"./dist/index.css"},"scripts":{"test":"vitest run","build":"tsup","test:watch":"vitest","type-check":"tsc --noEmit","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"asnewyla","email":"asnewyla@gmail.com"},"repository":{"url":"git+https://github.com/xavierDelaFuente/xd-components.git","type":"git","directory":"packages/radio"},"description":"Styled radio with label, validation error display, and accessibility","directories":{},"sideEffects":["*.css"],"_nodeVersion":"24.19.0","dependencies":{"@asnewyla/unstyled-radio":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.1.0","jsdom":"^24.0.0","react":"^18.3.0","vitest":"^2.0.0","react-dom":"^18.3.0","typescript":"^5.5.0","@vitest/coverage-v8":"^2.0.0","@testing-library/react":"^16.0.0","@testing-library/jest-dom":"^6.4.0","@testing-library/user-event":"^14.5.0"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/radio_0.2.0_1787564636522_0.4564501223688784","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@asnewyla/radio","version":"0.2.1","description":"Styled radio with label, validation error display, and accessibility","license":"MIT","repository":{"type":"git","url":"git+https://github.com/xavierDelaFuente/xd-components.git","directory":"packages/radio"},"publishConfig":{"access":"public"},"main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./styles.css":"./dist/index.css","./test-utils":{"types":"./dist/test-utils.d.ts","import":"./dist/test-utils.mjs","require":"./dist/test-utils.js"}},"sideEffects":["*.css"],"keywords":["react","radio","form","styled","accessible"],"peerDependencies":{"react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","@testing-library/react":"^16.0.0","@testing-library/user-event":"^14.5.0"},"peerDependenciesMeta":{"@testing-library/react":{"optional":true},"@testing-library/user-event":{"optional":true}},"dependencies":{"@asnewyla/unstyled-radio":"0.2.0"},"devDependencies":{"@testing-library/jest-dom":"^6.4.0","@testing-library/react":"^16.0.0","@testing-library/user-event":"^14.5.0","@vitest/coverage-v8":"^2.0.0","jsdom":"^24.0.0","react":"^18.3.0","react-dom":"^18.3.0","tsup":"^8.1.0","typescript":"^5.5.0","vitest":"^2.0.0"},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","type-check":"tsc --noEmit"},"_nodeVersion":"24.19.0","_id":"@asnewyla/radio@0.2.1","dist":{"integrity":"sha512-HzfH3O1X19eH8mhtzuU3xjBp2xM9vZCuNqk+SDbbwYPkRTgjo7KrlHWWZLPzdtiFfJliRz6evnCtth8tG1W63w==","shasum":"99c7421b275e0f58a730b4e51bccb090e46c4f08","tarball":"https://registry.npmjs.org/@asnewyla/radio/-/radio-0.2.1.tgz","fileCount":17,"unpackedSize":26013,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHx84J0Xq61XJvDIfNikICZ8JSSp0Zjnt6K6DT4pqYqXAiAlBfTe08Kt9fUzONVYMASPpFKkw0Rd2INOxUPWt5F3gQ=="}]},"_npmUser":{"name":"asnewyla","email":"asnewyla@gmail.com"},"directories":{},"maintainers":[{"name":"asnewyla","email":"asnewyla@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/radio_0.2.1_1787860427335_0.06238444947913835"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-24T09:43:56.437Z","modified":"2026-08-27T19:53:47.620Z","0.2.0":"2026-08-24T09:43:56.646Z","0.2.1":"2026-08-27T19:53:47.487Z"},"license":"MIT","keywords":["react","radio","form","styled","accessible"],"repository":{"type":"git","url":"git+https://github.com/xavierDelaFuente/xd-components.git","directory":"packages/radio"},"description":"Styled radio with label, validation error display, and accessibility","maintainers":[{"name":"asnewyla","email":"asnewyla@gmail.com"}],"readme":"# @asnewyla/radio\n\nStyled radio built on `@asnewyla/unstyled-radio`. Label association, inline\nvalidation error, full keyboard/focus accessibility.\n\n## Install\n\n```bash\nnpm install @asnewyla/radio\n```\n\nImport the stylesheet once, anywhere in your app:\n\n```ts\nimport '@asnewyla/radio/styles.css';\n```\n\n## Usage\n\n```tsx\nimport { Radio } from '@asnewyla/radio';\n\n<Radio label=\"Option A\" name=\"choice\" defaultChecked />\n<Radio label=\"Option B\" name=\"choice\" />\n\n<Radio label=\"Option A\" error=\"You must choose an option\" />\n\n// Controlled\n<Radio\n  label=\"Option A\"\n  checked={selected === 'a'}\n  onChange={() => setSelected('a')}\n/>\n```\n\n### Props\n\n| Prop | Type | Default |\n|---|---|---|\n| `label` | `string` (**required**) | — |\n| `error` | `string` | — |\n| `checked` / `defaultChecked` | `boolean` | — |\n| `onChange` | `(event: React.ChangeEvent<HTMLInputElement>) => void` | — |\n| `disabled` | `boolean` | `false` |\n| `id` | `string` | auto-generated via `useId()` |\n\n`error` doubles as the invalid-state flag — there's no separate `invalid`\nprop. Setting `error` sets `aria-invalid` on the input and links it via\n`aria-describedby` to the rendered error message; there's no way to end up\nwith one without the other. Same convention `@asnewyla/input` and\n`@asnewyla/checkbox` use.\n\n### Grouping radios\n\nTwo `Radio`s sharing a native `name` get correct browser-level exclusivity\nfor free — clicking one genuinely unchecks the other at the DOM level.\nThat's enough for a *display-only* group, or one you fully control\nyourself via `checked`/`onChange` on every member. For a group where you\nwant React to own \"which value is selected\" as shared state, use\n`RadioGroup` from `@asnewyla/radio-group` instead of wiring several\n`Radio`s up by hand:\n\n```tsx\nimport { RadioGroup } from '@asnewyla/radio-group';\nimport { Radio } from '@asnewyla/radio';\n\n<RadioGroup name=\"size\" defaultValue=\"md\">\n  <Radio label=\"Small\" value=\"sm\" />\n  <Radio label=\"Medium\" value=\"md\" />\n  <Radio label=\"Large\" value=\"lg\" />\n</RadioGroup>\n```\n\n`Radio` exports `RadioGroupProvider`/`useRadioGroupContext` itself (that's\nhow it consumes an ancestor group), but you'd only reach for those\ndirectly if you were building something like `RadioGroup` yourself — see\n`@asnewyla/radio-group`'s README for the underlying limitation it exists\nto fix (an uncontrolled radio's own state can go stale when a sibling is\nselected instead, since browsers don't fire a change event on the\ndeselected radio).\n\n### Theming\n\nOverride the CSS custom properties — defaults adapt automatically to\n`prefers-color-scheme` via `@asnewyla/tokens`:\n\n```css\n:root {\n  --xd-color-primary: #0d9488;\n  --xd-color-destructive: #dc2626;\n}\n```\n\n## License\n\nMIT\n","readmeFilename":""}