{"_id":"@3xjn/prism","name":"@3xjn/prism","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@3xjn/prism","version":"0.1.0","description":"A typed Roblox UI kit for rbxts-react.","main":"out/lib/init.luau","types":"out/lib/index.d.ts","publishConfig":{"access":"public"},"scripts":{"test":"node scripts/run-units-assertions.cjs","build":"rbxtsc","prepack":"npm run lint && npm run typecheck && npm test && npm run build","fallow":"fallow --format human","fallow:json":"fallow --format json --quiet","fallow:dead-code":"fallow dead-code --format human","fallow:dupes":"fallow dupes --format human","fallow:health":"fallow health --score --hotspots --targets --format human","fallow:audit":"fallow audit --base origin/master --format human","typecheck":"tsc --noEmit -p tsconfig.json","lint":"eslint src --ext .ts,.tsx","format":"prettier --check ."},"peerDependencies":{"@rbxts/react":"17.3.7-ts.1","@rbxts/react-roblox":"17.3.7-ts.1"},"devDependencies":{"@rbxts/compiler-types":"3.0.0-types.0","@rbxts/react":"17.3.7-ts.1","@rbxts/react-roblox":"17.3.7-ts.1","@rbxts/types":"^1.0.943","@rbxts/ui-labs":"2.4.2","@typescript-eslint/parser":"8.58.2","eslint":"8.57.1","eslint-plugin-roblox-ts":"1.4.0","fallow":"^2.98.0","prettier":"3.8.3","typescript":"5.8.3"},"repository":{"type":"git","url":"git+https://github.com/3xjn/prism.git"},"bugs":{"url":"https://github.com/3xjn/prism/issues"},"homepage":"https://github.com/3xjn/prism#readme","keywords":["roblox","roblox-ts","react","ui","design-system"],"author":{"name":"3xjn"},"license":"MIT","gitHead":"b5ab38b56121468f7e5be0512f9d508b91c29d0d","_id":"@3xjn/prism@0.1.0","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-lxsQNsgzjsf4d/lnv7IHN633oYU99IDyJg+ctBaR/Te6hlT2UkZ2fL0q9i4d4c+Itz14/HsVn0Jszad8FPXApQ==","shasum":"fc27024bb8269f457f3850e128317ed83b19d88c","tarball":"https://registry.npmjs.org/@3xjn/prism/-/prism-0.1.0.tgz","fileCount":365,"unpackedSize":1775758,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDVLMyTciPKB6Xuk9onEjSkCKcyrrnxW0dGcdv8vBqRMAiEAydBaS9VU4CpZQTV5vFZzWnxM/3WZXAc0ojvnmbxvpxc="}]},"_npmUser":{"name":"3xjn","email":"mcphersonasher@gmail.com"},"directories":{},"maintainers":[{"name":"3xjn","email":"mcphersonasher@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/prism_0.1.0_1788117992179_0.5739266525578732"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-30T19:26:31.982Z","0.1.0":"2026-08-30T19:26:32.325Z","modified":"2026-08-30T19:26:32.577Z"},"maintainers":[{"name":"3xjn","email":"mcphersonasher@gmail.com"}],"description":"A typed Roblox UI kit for rbxts-react.","homepage":"https://github.com/3xjn/prism#readme","keywords":["roblox","roblox-ts","react","ui","design-system"],"repository":{"type":"git","url":"git+https://github.com/3xjn/prism.git"},"author":{"name":"3xjn"},"bugs":{"url":"https://github.com/3xjn/prism/issues"},"license":"MIT","readme":"# Prism\n\nA Roblox TypeScript UI kit for `rbxts-react` — typed components, theme tokens, and Roblox-native sizing.\n\n## Components\n\n| | |\n| --- | --- |\n| Layout | `Box`, `Stack`, `Divider`, `Card`, `ScrollArea` |\n| Text and media | `Text`, `Icon`, `Image`, `Avatar` |\n| Inputs and forms | `Button`, `Pressable`, `Input`, `KeybindInput`, `Checkbox`, `Switch`, `StepperInput`, `Slider` |\n| Feedback | `Progress`, `CircularProgress`, `Backdrop` |\n| Navigation | `SegmentedControl`, `Tabs`, `Menu`, `Select` |\n| Overlays | `WorldPortal`, `Popover`, `Modal`, `Tooltip` |\n| Utility | `Draggable` |\n\nAlso: `@3xjn/prism` exports ThemeProvider and tokens, motion hooks, unit helpers, and `mountPrism` for Luau interop.\n\n## Setup\n\nNeeds Node, Rojo, and Roblox Studio.\n\n```bash\nnpm install\nnpm run build\nrojo serve\n```\n\n## Usage\n\n```bash\nnpm install @3xjn/prism @rbxts/react @rbxts/react-roblox\n```\n\n```tsx\nimport React from \"@rbxts/react\";\nimport { Button, Divider, Stack, Text, ThemeProvider, theme } from \"@3xjn/prism\";\n\nexport function ServerControls() {\n\treturn (\n\t\t<ThemeProvider>\n\t\t\t<Stack width={280} bg={theme.primary.main} radius=\"md\" p=\"md\" gap=\"sm\">\n\t\t\t\t<Text size=\"lg\" color={theme.text.inverse} text=\"Server controls\" />\n\t\t\t\t<Divider color={theme.border.subtle} />\n\t\t\t\t<Button variant=\"light\" color=\"secondary\" label=\"Save changes\" />\n\t\t\t</Stack>\n\t\t</ThemeProvider>\n\t);\n}\n```\n\nBecause Prism uses a custom npm scope, add that scope beside `@rbxts` in both consumer mappings:\n\n```json\n// tsconfig.json\n\"typeRoots\": [\"node_modules/@rbxts\", \"node_modules/@3xjn\"]\n```\n\n```json\n// default.project.json, under rbxts_include\n\"node_modules\": {\n\t\"$className\": \"Folder\",\n\t\"@rbxts\": { \"$path\": \"node_modules/@rbxts\" },\n\t\"@3xjn\": { \"$path\": \"node_modules/@3xjn\" }\n}\n```\n\nText goes through `text` / `label` props — JSX text children aren't type-supported on `forwardRef` components in this toolchain.\n\nControlled inputs are plain React state:\n\n```tsx\nconst [query, setQuery] = React.useState(\"\");\n\n<Input value={query} onChange={setQuery} placeholder=\"Search\" variant=\"outline\" fullWidth />\n```\n\n## Tokens and units\n\nIntent props take strings (`color=\"success\"`); concrete color props take `theme.*` refs or raw `Color3` values. Dotted strings like `\"text.secondary\"` are not accepted.\n\n```tsx\n<Button color=\"success\" variant=\"filled\" label=\"Publish\" />\n<Text color={theme.text.secondary} text=\"Autosaved just now\" />\n<Stack bg={Color3.fromRGB(20, 20, 20)} radius=\"lg\" p=\"md\" />\n```\n\nSizing is Roblox-native — numbers are pixel offsets, percentage strings are scale, `UDim`/`UDim2` pass through:\n\n```tsx\n<Stack width={280} />\n<Stack width=\"50%\" />\n<Stack width={new UDim(0, 280)} />\n```\n\nSize tokens (`\"xs\"` … `\"xl\"`) cover spacing, radius, and text size. Invalid tokens throw in dev.\n\n## Slot props\n\nEscape hatch for instance properties the component API doesn't cover. Applied last.\n\n```tsx\n<Button\n\tlabel=\"Danger\"\n\tcolor=\"error\"\n\tvariant=\"outline\"\n\tslotProps={{\n\t\troot: { LayoutOrder: 10 },\n\t\tstroke: { Thickness: 2 },\n\t}}\n/>\n```\n\n## Motion\n\n`useMotion` animates numbers, `Color3` values, and theme refs with the same tokens Prism uses internally:\n\n```tsx\nconst animated = useMotion({\n\tvalues: {\n\t\tscale: hovered ? 1.04 : 1,\n\t\tbg: hovered ? theme.primary.light : theme.background.surface,\n\t},\n\ttransition: { duration: \"fast\", easing: \"out\" },\n});\n```\n\nComponents own their internal motion — overriding the same property via `slotProps` can fight a managed animation.\n\n## Playground\n\nui-labs stories live in `src/playground/stories`. `index.storybook.ts` is the storybook config; `index.ts` imports each `*.story` module so roblox-ts emits them. Add `*.story.tsx` files there for new components.\n\n## Non-goals\n\nWally, polymorphic `as` props, app shell patterns, and timeline/keyframe animation.\n","readmeFilename":"README.md","_rev":"1-334ebb65b386a036d6a37f910db3a0a5"}