{"_id":"@boopalakannan-ux/test-ds","_rev":"4-0b0acc6079d29966cff3e87b4dfaaaf6","name":"@boopalakannan-ux/test-ds","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@boopalakannan-ux/test-ds","version":"0.1.0","keywords":["design-system","react","figma-make"],"license":"MIT","_id":"@boopalakannan-ux/test-ds@0.1.0","maintainers":[{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"}],"dist":{"shasum":"51e673670aef40ac491f6cb4cd93f8f41582117b","tarball":"https://registry.npmjs.org/@boopalakannan-ux/test-ds/-/test-ds-0.1.0.tgz","fileCount":6,"integrity":"sha512-FtURGLo4lCq1akLMHb9oL8LMHxa5QfoEB0PFTD0PdvKvfuc7c7X7E1XCkNrJJk6/RqWXl24aIZ+I6moup6lZJw==","signatures":[{"sig":"MEYCIQCtioEkh1Irj4L3uBHAeqt6WLIZ6stJ0yTi3HZaBePEuQIhAK2T9Pj7e0dpcvTPuLgUwHjDULnIgSPz9qGLv9HghzO3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":11125},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./styles.css":"./dist/index.css"},"scripts":{"build":"vite build && tsc --emitDeclarationOnly","prepublishOnly":"npm run build"},"_npmUser":{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"},"_npmVersion":"11.12.1","description":"A small SaaS button system — hierarchy, size, and content variants with semantic design tokens.","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.11","react":"^18.3.1","react-dom":"^18.3.1","typescript":"^5.6.3","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@vitejs/plugin-react":"^4.3.4","vite-plugin-lib-inject-css":"^2.1.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/test-ds_0.1.0_1786074466727_0.03287594378819958","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@boopalakannan-ux/test-ds","version":"0.2.0","keywords":["design-system","react","figma-make"],"license":"MIT","_id":"@boopalakannan-ux/test-ds@0.2.0","maintainers":[{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"}],"dist":{"shasum":"cae95990a2005942d2748006f2135069143fcb49","tarball":"https://registry.npmjs.org/@boopalakannan-ux/test-ds/-/test-ds-0.2.0.tgz","fileCount":8,"integrity":"sha512-TabWG9YdCl+srE5btan+Dm4B8SpKmDMf4DrvasB1fdNCFR+/yxZeKBKShJ0FmmYs2jfgCiFaWoBLlMpCQCvX5Q==","signatures":[{"sig":"MEYCIQD/6stDKRLZSErutnI273kor2xTzmNKG7kOHi0ZtwOblQIhAJYgIKuvFI899XhBkIKyH5RRrjIv4JReCtB4FzaUaQew","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26540},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./styles.css":"./dist/index.css"},"scripts":{"build":"vite build && tsc --emitDeclarationOnly","prepublishOnly":"npm run build"},"_npmUser":{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"},"_npmVersion":"11.12.1","description":"A small SaaS component system — Button, Input and Badge, driven by semantic design tokens mirrored 1:1 from Figma.","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.11","react":"^18.3.1","react-dom":"^18.3.1","typescript":"^5.6.3","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@vitejs/plugin-react":"^4.3.4","vite-plugin-lib-inject-css":"^2.1.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/test-ds_0.2.0_1786077252977_0.20482114528488626","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@boopalakannan-ux/test-ds","version":"0.3.0","keywords":["design-system","react","figma-make"],"license":"MIT","_id":"@boopalakannan-ux/test-ds@0.3.0","maintainers":[{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"}],"dist":{"shasum":"d8a0109863b2117b01309aa04cb8fcc705768ce7","tarball":"https://registry.npmjs.org/@boopalakannan-ux/test-ds/-/test-ds-0.3.0.tgz","fileCount":8,"integrity":"sha512-fW/Rd2ozt9FgvXnTup/gT09jnBYeAwHR+hTDuuX704HELceJ4Wt7XQ+0DBcAbo/71+N6LApJeMkirF4hAtLJuw==","signatures":[{"sig":"MEUCIQDPzsEHAgvtCj3PhKND9lLTyCk8Lozj74ueXcgz8Ti2UgIgMu+N556woVp2Udqp8MaDaQXWSFvRCNZVRnboZMAua9I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27105},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./styles.css":"./dist/index.css"},"scripts":{"build":"vite build && tsc --emitDeclarationOnly","prepublishOnly":"npm run build"},"_npmUser":{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"},"_npmVersion":"11.12.1","description":"A small SaaS component system — Button, Input and Badge, driven by semantic design tokens mirrored 1:1 from Figma.","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.11","react":"^18.3.1","react-dom":"^18.3.1","typescript":"^5.6.3","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@vitejs/plugin-react":"^4.3.4","vite-plugin-lib-inject-css":"^2.1.1"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/test-ds_0.3.0_1786078454949_0.4831366989810335","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@boopalakannan-ux/test-ds","version":"0.4.0","description":"A small SaaS component system — Button, Input, Badge and Table, driven by semantic design tokens mirrored 1:1 from Figma.","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./styles.css":"./dist/index.css"},"sideEffects":["**/*.css"],"scripts":{"build":"vite build && tsc --emitDeclarationOnly","prepublishOnly":"npm run build"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0"},"devDependencies":{"@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@vitejs/plugin-react":"^4.3.4","react":"^18.3.1","react-dom":"^18.3.1","typescript":"^5.6.3","vite":"^5.4.11","vite-plugin-lib-inject-css":"^2.1.1"},"keywords":["design-system","react","figma-make"],"license":"MIT","_id":"@boopalakannan-ux/test-ds@0.4.0","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-Bvkm0G4cpZ9V9pkKddlKtfOWmuSuC3XcL48pKv65SugCQQJsj+ob+MnnqAJAMaA0XmFadMuvAzd31+0VBrdb6Q==","shasum":"f8b208f2ba7dd1b233cb340417e29026576061d2","tarball":"https://registry.npmjs.org/@boopalakannan-ux/test-ds/-/test-ds-0.4.0.tgz","fileCount":9,"unpackedSize":40556,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCJiYAIQMgyNOj1L7ubocaMfbyeb5MWl6hkp4L+fAgSigIgfNmDcrLTC8abo5Mz1+CVWiQaSQYGPfI8olcC/iDB1aE="}]},"_npmUser":{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"},"directories":{},"maintainers":[{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/test-ds_0.4.0_1786510829250_0.82870355312108"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-07T03:47:46.532Z","modified":"2026-08-12T05:00:29.568Z","0.1.0":"2026-08-07T03:47:46.889Z","0.2.0":"2026-08-07T04:34:13.134Z","0.3.0":"2026-08-07T04:54:15.083Z","0.4.0":"2026-08-12T05:00:29.388Z"},"license":"MIT","keywords":["design-system","react","figma-make"],"description":"A small SaaS component system — Button, Input, Badge and Table, driven by semantic design tokens mirrored 1:1 from Figma.","maintainers":[{"name":"boopalakannan-ux","email":"boobalankannan6@gmail.com"}],"readme":"# @boopalakannan-ux/test-ds\n\nA small React component system — Button, Input, Badge, Table — driven by semantic\ndesign tokens mirrored 1:1 from a Figma library. Built for use as a Figma Make kit.\n\n```bash\nnpm install @boopalakannan-ux/test-ds\n```\n\n```tsx\nimport \"@boopalakannan-ux/test-ds/styles.css\";\nimport { Button, Input, Badge, Table } from \"@boopalakannan-ux/test-ds\";\n```\n\nThe stylesheet is a **separate export**. Import it once at your app root or every\ncomponent renders unstyled.\n\n## What's inside\n\n```\nsrc/\n  Button.tsx / .css\n  Input.tsx  / .css\n  Badge.tsx  / .css\n  Table.tsx  / .css\n  tokens.css     the code mirror of the Figma Semantic, Spacing and Radius collections\n  index.ts\nguidelines.md    how Make should use the system  ← the highest-leverage file\n```\n\n## Components\n\n### Button\n\n```tsx\n<Button variant=\"primary\" size=\"md\">Save changes</Button>\n<Button variant=\"secondary\" leadingIcon={<Download />}>Export PDF</Button>\n<Button variant=\"destructive\" loading>Deleting</Button>\n<Button variant=\"ghost\" leadingIcon={<Settings />} aria-label=\"Settings\" />\n```\n\n| Prop | Type | Default |\n| --- | --- | --- |\n| `variant` | `primary \\| secondary \\| ghost \\| destructive` | `primary` |\n| `size` | `sm \\| md \\| lg` | `md` |\n| `loading` | `boolean` | `false` |\n| `leadingIcon` / `trailingIcon` | `ReactNode` | — |\n\n### Input\n\n```tsx\n<Input\n  label=\"Email\"\n  status={error ? \"error\" : \"default\"}\n  helpText={error ?? \"We'll only use this for sign-in.\"}\n/>\n```\n\n| Prop | Type | Default |\n| --- | --- | --- |\n| `size` | `sm \\| md \\| lg` | `md` |\n| `status` | `default \\| error \\| success` | `default` |\n| `label` | `string` — plain text only, see below | — |\n| `helpText` | `ReactNode` | — |\n| `leadingAdornment` / `trailingAdornment` | `ReactNode` | — |\n| `required`, `fullWidth` | `boolean` | `false` |\n\n`label` is a `string`, deliberately. Its contents land inside `<label htmlFor>` and\nbecome the field's accessible name — a Badge in there makes a screen reader announce\n\"Workspace name Pro\" as the name of the input.\n\n### Badge\n\n```tsx\n<Badge color=\"green\" dot>Available</Badge>\n<Badge variant=\"filled\" color=\"red\">Failed</Badge>\n```\n\n| Prop | Type | Default |\n| --- | --- | --- |\n| `variant` | `soft \\| filled \\| outlined \\| ghost` | `soft` |\n| `color` | `gray \\| blue \\| green \\| yellow \\| red \\| purple \\| indigo \\| teal` | `gray` |\n| `size` | `sm \\| md \\| lg` | `md` |\n| `dot` | `boolean` — live status only | `false` |\n| `count` | `number` | — |\n| `onDismiss` | `() => void` | — |\n\n### Table\n\n```tsx\n<Table\n  caption=\"Charge points across all sites\"\n  rows={sorted}\n  rowKey={(cp) => cp.id}\n  sort={sort}\n  onSortChange={setSort}\n  activeKey={openId}\n  columns={[\n    { key: \"site\", header: \"Site name\", sortable: true,\n      cell: (cp) => cp.name, subCell: (cp) => cp.site },\n    { key: \"power\", header: \"Power\", align: \"end\", sortable: true,\n      cell: (cp) => `${cp.kw} kW` },\n    { key: \"status\", header: \"Status\",\n      cell: (cp) => <Badge color={statusColor(cp.status)} dot>{cp.status}</Badge> },\n  ]}\n/>\n```\n\n`Table` renders the sort control and sets `aria-sort`, but **does not sort your data** —\nyou hold `sort` in state and sort the rows. That keeps client-side and server-side\nsorting the same shape.\n\n`selectedKeys` + `onSelectionChange` enable the checkbox column with indeterminate\nselect-all. `activeKey` marks the row open in a detail panel and outranks selection.\n\n## Token parity with Figma\n\n`src/tokens.css` mirrors three Figma collections name-for-name and value-for-value:\n\n| Collection | Count | Prefix |\n| --- | --- | --- |\n| Semantic | 70 | `--color-*` |\n| Spacing | 10 | `--spacing-*` |\n| Radius | 6 | `--radius-*` |\n\nEach Figma variable carries its CSS name as WEB code syntax, so Figma's inspect panel\nshows `var(--color-action-primary)` directly.\n\nEvery Button, Input and Badge variant in Figma is bound to these variables — zero\nhardcoded fills across 126 variants. There is **no build step** syncing Figma and code;\nwhen you add a variable in one, add it in the other in the same pass.\n\nTwo rules worth knowing:\n\n- `--color-status-error` and `--color-action-destructive` are both red/600. An errored\n  field and a delete button are the same idea, so they're the same red.\n- Never use a `--size-*` token as spacing. `--size-md-height` is a control height that\n  happens to equal 40px; `--spacing-4xl` is the gap. They diverge the day someone\n  changes control height.\n\nTo retheme, override the custom properties on `:root`.\n\n## How this maps back to Figma\n\n| Figma property | Code |\n| --- | --- |\n| `Hierarchy` (Primary/Secondary/Ghost/Destructive) | `variant` |\n| `Size` (Large/Medium/Small) | `size` (`lg`/`md`/`sm`) |\n| `State=Disabled` | `disabled` |\n| `State=Hover` / `State=Pressed` / `State=Focused` | CSS pseudo-classes — **not props** |\n| `Status=Error` / `Status=Success` | `status` — **is** a prop |\n| `Content=Loading` | `loading` |\n| `Content=Icon Only` | omit `children`, pass `aria-label` |\n\nState is pointer position, so CSS derives it and Figma needs a variant to show it.\nStatus is application state, so CSS can't know it and it comes in as a prop. That\nasymmetry is intentional — don't \"fix\" it in either direction.\n\n## Publishing\n\n```bash\nnpm install\nnpm run build          # verify it compiles\nnpm login              # first time only\nnpm publish --access public\n```\n\nVersions are **immutable** on both public npm and Figma's private registry — you\ncannot overwrite, and unpublishing is only possible within 72 hours. Bump the version\nrather than trying to fix in place.\n\nFor Figma's private registry, see `.npmrc.example`.\n\n## Using it in a Make kit\n\n1. New Make file → **Settings** → **Create a kit** → **Assemble your kit**\n2. **npm packages** → search `@boopalakannan-ux/test-ds` (public, no scope setup needed)\n3. Paste `guidelines.md` into `guidelines/Guidelines.md`\n4. Optionally add **Library styles** to import the Figma variables\n5. Test with a prompt, then **Publish kit**\n\nMake kits flatten Figma variables into raw CSS values rather than preserving names, so\n`guidelines.md` is where the token rules actually live. It is the highest-leverage file\nin this repo — more than any component.\n","readmeFilename":"README.md"}