{"_id":"@atinuda.io/ui","name":"@atinuda.io/ui","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@atinuda.io/ui","version":"0.1.0","description":"Accessible, composable React component primitives built for real interfaces. Designed with WCAG 2.2 AA practices in mind.","license":"MIT","type":"module","main":"./dist/index.js","exports":{".":{"import":"./dist/index.js"},"./styles.css":"./dist/styles.css","./tokens":"./dist/tokens.js"},"sideEffects":["**/*.css"],"scripts":{"build":"node scripts/build.mjs","test":"node --test --test-reporter=spec \"test/**/*.test.js\""},"keywords":["react","components","ui","design-system","accessibility","design-tokens"],"author":{"name":"Atinuda LLC"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"devDependencies":{"esbuild":"^0.28.0"},"publishConfig":{"access":"public"},"_id":"@atinuda.io/ui@0.1.0","_nodeVersion":"22.17.1","_npmVersion":"11.5.2","dist":{"integrity":"sha512-3cg6TsDrshutyvIbsLxEpfAqt+CTETd353PQA0cPogNDVAnAOj5e8W2YFWU1pCzgMVU1jfFjz1xY+bI/ahQIXQ==","shasum":"2864c35c3f201ee3c9851dbfabc0552df3d56617","tarball":"https://registry.npmjs.org/@atinuda.io/ui/-/ui-0.1.0.tgz","fileCount":7,"unpackedSize":72398,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID4+hP33v/Evk2Ylcp8lge+gafIHCkBwZaJI6JnGr1mcAiEA1h0BPOY9WixNCRZO3DZoe3dpKz8W/i8lc1iW8c+3HwM="}]},"_npmUser":{"name":"atinuda","email":"owner@atinuda.io"},"directories":{},"maintainers":[{"name":"atinuda","email":"owner@atinuda.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ui_0.1.0_1787392256674_0.5321217432917196"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-22T09:50:56.411Z","0.1.0":"2026-08-22T09:50:56.841Z","modified":"2026-08-22T09:50:57.248Z"},"maintainers":[{"name":"atinuda","email":"owner@atinuda.io"}],"description":"Accessible, composable React component primitives built for real interfaces. Designed with WCAG 2.2 AA practices in mind.","keywords":["react","components","ui","design-system","accessibility","design-tokens"],"author":{"name":"Atinuda LLC"},"license":"MIT","readme":"# @atinuda.io/ui\n\n> Accessible by default. Composable by design. Built for real interfaces.\n\nA small set of accessible, composable React component primitives and design tokens, extracted from the work demonstrated in the [Atinuda](https://atinuda.io) UI lab.\n\n**Status:** `0.1.0` — an evolving component and design-system laboratory being developed as a reusable UI library. Not published to npm.\n\n## Philosophy\n\n- **Semantic HTML** — components render the right element (`<button>`, `<input>`, `<fieldset>`, `<nav>`), not clickable `<div>`s.\n- **Accessibility** — keyboard interaction, visible focus, accessible names, label/error association, semantic status messaging, and reduced-motion support are built into the APIs.\n- **Composition** — props pass through to the underlying element; `className` is always supported and appended last so consumers can override.\n- **Design tokens** — color, typography, spacing, radius, shadow, motion, and breakpoints are exposed as CSS custom properties and mirrored in JS.\n- **Native behavior where appropriate** — native form controls are preferred; ARIA is added only where native semantics are insufficient.\n- **No business logic, no unnecessary abstraction.**\n\nDesigned with WCAG 2.2 AA practices in mind. This is **not** a formal WCAG conformance certification.\n\n## Installation\n\nThis package is part of the Atinuda monorepo workspace (`packages/ui`). The `exports` map points consumers at the built distributable in `dist/`, so build it first:\n\n```sh\nnpm run build\n```\n\nThen consume it through the public API:\n\n```js\nimport { Button } from '@atinuda.io/ui';\nimport '@atinuda.io/ui/styles.css';\n```\n\nDo not import directly from `src/components/...` — those are internal module paths. The public surface is the package root (`@atinuda.io/ui`), the stylesheet (`@atinuda.io/ui/styles.css`), and the tokens module (`@atinuda.io/ui/tokens`).\n\n## Usage\n\n```jsx\nimport {\n  Button,\n  IconButton,\n  Input,\n  Textarea,\n  Select,\n  Checkbox,\n  RadioGroup,\n  Radio,\n  Alert,\n  StatusMessage,\n  Card,\n  Badge,\n  Tabs,\n  Breadcrumbs,\n} from '@atinuda.io/ui';\nimport '@atinuda.io/ui/styles.css';\n```\n\n### Buttons\n\n```jsx\n<Button variant=\"primary\" size=\"md\">Save</Button>\n<Button variant=\"outline\" disabled>Cancel</Button>\n<IconButton label=\"Search\" onClick={openSearch}><SearchIcon /></IconButton>\n```\n\n`Button` always renders a `<button>`. Links should stay links — render an `<a>` (or router `<Link>`) and apply the `atui-btn` classes directly.\n\n### Forms\n\n```jsx\n<label htmlFor=\"email\">Email</label>\n<Input id=\"email\" type=\"email\" aria-invalid=\"true\" aria-describedby=\"email-error\" />\n<p id=\"email-error\" role=\"alert\">Enter a valid email.</p>\n\n<Textarea id=\"notes\" rows={4} placeholder=\"Notes…\" />\n\n<Select id=\"engagement\" defaultValue=\"consulting\">\n  <option value=\"consulting\">Consulting</option>\n  <option value=\"project\">Project delivery</option>\n</Select>\n\n<Checkbox label=\"Send me updates\" hint=\"No more than once a week.\" />\n\n<RadioGroup legend=\"Density\">\n  <Radio name=\"density\" value=\"compact\" label=\"Compact\" />\n  <Radio name=\"density\" value=\"comfortable\" label=\"Comfortable\" />\n</RadioGroup>\n```\n\n### Feedback\n\n```jsx\n<Alert tone=\"success\" title=\"Saved\" icon={<CheckIcon />}>Your changes were saved.</Alert>\n<StatusMessage politeness=\"polite\">{message}</StatusMessage>\n```\n\n`Alert` uses `role=\"alert\"` for the `error` tone and `role=\"status\"` otherwise. `StatusMessage` is a live region (`aria-live` polite/assertive/off).\n\n### Content & navigation\n\n```jsx\n<Card as=\"article\">\n  <CardHeader><CardTitle>Title</CardTitle></CardHeader>\n  <CardBody>Body content</CardBody>\n</Card>\n\n<Badge tone=\"success\">Verified</Badge>\n\n<Tabs items={[\n  { id: 'overview', label: 'Overview', content: <p>…</p> },\n  { id: 'tokens', label: 'Tokens', content: <p>…</p> },\n]} />\n\n<Breadcrumbs items={[\n  { label: 'Labs', href: '/labs' },\n  { label: 'Atinuda UI', href: '/labs/atinuda-ui' },\n  { label: 'Navigation' },\n]} />\n```\n\n`Tabs` implements the WAI-ARIA tabs pattern with roving `tabindex` and `ArrowLeft`/`ArrowRight`/`Home`/`End` keyboard support.\n\n## Design tokens\n\nTokens are defined as CSS custom properties in `src/styles/styles.css` (dark-first) and mirrored in `src/tokens/tokens.js` for programmatic use. Override them in your app to retheme:\n\n```css\n:root {\n  --atui-primary: 265 84% 68%;\n  --atui-radius-lg: 0.75rem;\n}\n```\n\nA light theme is available via `data-atui-theme=\"light\"` on any wrapper (or `<html>`).\n\nAll component styles are scoped to `.atui-*` class names, so the package never affects surrounding application markup.\n\n## Components\n\n| Component | Element | Notes |\n| --- | --- | --- |\n| `Button` | `<button>` | variants: primary, secondary, outline, ghost, destructive; sizes: sm, md, lg |\n| `IconButton` | `<button>` | requires `label` (aria-label) |\n| `Input` | `<input>` | native attributes pass through |\n| `Textarea` | `<textarea>` | vertical resize |\n| `Select` | `<select>` | native options |\n| `Checkbox` | `<input type=\"checkbox\">` | label-wrapped, optional hint |\n| `RadioGroup` / `Radio` | `<fieldset>` / `<input type=\"radio\">` | legend + grouped radios |\n| `Alert` | `<div role>` | tones: info, success, warning, error |\n| `StatusMessage` | `<div role=\"status\">` | polite / assertive / off |\n| `Card` (+ slots) | `<div>` / `as` | header, title, description, body, footer |\n| `Badge` | `<span>` | tones: primary, secondary, success, warning, destructive, accent, neutral |\n| `Tabs` | `<div role=\"tablist\">` | WAI-ARIA keyboard support |\n| `Breadcrumbs` | `<nav>` | `aria-current=\"page\"` on last item |\n\n## Peer dependencies\n\n- `react` >= 18\n- `react-dom` >= 18\n\nReact is a peer dependency so consuming apps never bundle a duplicate runtime.\n\n## License\n\nMIT © Atinuda LLC\n","readmeFilename":"README.md","_rev":"1-dc8b2c317d92f8cfba0ee2327465e16c"}