{"_id":"9am-ui","_rev":"3-187dae59685090b3477f604e3f322571","name":"9am-ui","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"9am-ui","version":"1.0.0","keywords":["fivem","nui","cef","shadcn","shadcn-registry","react","tailwindcss","ui"],"license":"MIT","_id":"9am-ui@1.0.0","maintainers":[{"name":"ata61","email":"caglayanmustafaata@gmail.com"}],"homepage":"https://github.com/ilovehugetits/9am-ui#readme","bugs":{"url":"https://github.com/ilovehugetits/9am-ui/issues"},"bin":{"9am-ui":"cli/index.ts"},"dist":{"shasum":"2d970e18d3a33a85266c7d9c4d8661260fce5c25","tarball":"https://registry.npmjs.org/9am-ui/-/9am-ui-1.0.0.tgz","fileCount":200,"integrity":"sha512-SPEoRt6vGW1ue6PhRe2esB6PGX8yqfsPMRU4twQ95BTC18SeYfsKIywiir+w4bYhEGq7vJeDfgVND/IJffZsPQ==","signatures":[{"sig":"MEUCIEKcUdiZvpaJBs5P8khpiZmsLJ4LsP51wCvYi0uJeJXTAiEA65TgYu3KOj61qevxOiZn0wRwfUp1v5mx+ETS7SBjYn0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1624438},"type":"module","gitHead":"b658542f3411c69d2bb5e885af28f2c6ae86d661","scripts":{"docs":"bun run --cwd apps/docs dev","build":"bun run fonts && bun run registry:gen && bun run registry:build","check":"bun cli/index.ts check","fonts":"bun scripts/build-fonts.ts","doctor":"bun cli/index.ts doctor","preview":"vite --config apps/preview/vite.config.ts","typecheck":"tsc --noEmit","docs:build":"bun run --cwd apps/docs build","registry:gen":"bun scripts/build-registry.ts","preview:build":"vite build --config apps/preview/vite.config.ts","registry:build":"bunx --bun shadcn@latest build --output r"},"_npmUser":{"name":"ata61","email":"caglayanmustafaata@gmail.com"},"repository":{"url":"git+https://github.com/ilovehugetits/9am-ui.git","type":"git"},"workspaces":["apps/docs"],"_npmVersion":"11.6.2","description":"The shared design language, NUI plumbing and FiveM CEF workarounds behind every 9AM Studios script — an open shadcn registry.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"clsx":"^2.1.1","react":"19.2.8","motion":"^12.42.2","zustand":"^5.0.14","recharts":"^3.10.0","react-dom":"19.2.8","tailwindcss":"^4.3.3","tailwind-merge":"^3.6.0","tw-animate-css":"^1.4.0","react-day-picker":"^10.0.1","@tailwindcss/vite":"^4.3.3","@radix-ui/react-slot":"^1.3.1","@radix-ui/react-tabs":"^1.1.19","@radix-ui/react-label":"^2.1.13","@tanstack/react-table":"^8.21.3","@radix-ui/react-dialog":"^1.1.21","@radix-ui/react-select":"^2.3.5","@radix-ui/react-switch":"^1.3.5","@radix-ui/react-popover":"^1.1.21","@radix-ui/react-tooltip":"^1.2.14","class-variance-authority":"^0.7.1"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.1.5","@types/bun":"^1.3.5","typescript":"^5.9.3","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.4"},"_npmOperationalInternal":{"tmp":"tmp/9am-ui_1.0.0_1786722878269_0.8209758205706781","host":"s3://npm-registry-packages-npm-production"},"deprecated":"bin was TypeScript; use 1.1.0+ for npx support"},"1.1.0":{"name":"9am-ui","version":"1.1.0","keywords":["fivem","nui","cef","shadcn","shadcn-registry","react","tailwindcss","ui"],"license":"MIT","_id":"9am-ui@1.1.0","maintainers":[{"name":"ata61","email":"caglayanmustafaata@gmail.com"}],"homepage":"https://github.com/ilovehugetits/9am-ui#readme","bugs":{"url":"https://github.com/ilovehugetits/9am-ui/issues"},"bin":{"9am-ui":"dist/9am-ui.mjs"},"dist":{"shasum":"fb486fbc84c51b79d02466ac7c451df532ea1b2f","tarball":"https://registry.npmjs.org/9am-ui/-/9am-ui-1.1.0.tgz","fileCount":201,"integrity":"sha512-8pg6dLkMOzmFI7juHMWdT0MDnkQQ8Emn+/ifTr8MtXRd+KN1M/ehyWf7Jwbj0OtKXDjkiwHDaOMFakEQjagUAQ==","signatures":[{"sig":"MEYCIQCc69RXhYamiEjzT8+pffWZ2f/uUhZBQHyeUjUrV00oOQIhAKyrqUZlLnjaGedkI4ZTHkrKRbDFEOaHK5yP/REagLVv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/9am-ui@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1636127},"type":"module","gitHead":"b70e7a80edcd59b05833f264ec69adfc0a69e60e","scripts":{"docs":"bun run --cwd apps/docs dev","build":"bun run fonts && bun run registry:gen && bun run registry:build && bun run cli:build","check":"bun cli/index.ts check","fonts":"bun scripts/build-fonts.ts","doctor":"bun cli/index.ts doctor","preview":"vite --config apps/preview/vite.config.ts","cli:build":"bun build cli/index.ts --target=node --format=esm --outfile=dist/9am-ui.mjs --banner \"#!/usr/bin/env node\"","typecheck":"tsc --noEmit","docs:build":"bun run --cwd apps/docs build","registry:gen":"bun scripts/build-registry.ts","preview:build":"vite build --config apps/preview/vite.config.ts","prepublishOnly":"bun run cli:build","registry:build":"bunx --bun shadcn@latest build --output r"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c41ebc0-a29d-420d-bd3c-be0e762e6148"}},"repository":{"url":"git+https://github.com/ilovehugetits/9am-ui.git","type":"git"},"workspaces":["apps/docs"],"_npmVersion":"12.0.2","description":"The shared design language, NUI plumbing and FiveM CEF workarounds behind every 9AM Studios script — an open shadcn registry.","directories":{},"_nodeVersion":"24.19.0","dependencies":{"clsx":"^2.1.1","react":"19.2.8","motion":"^12.42.2","zustand":"^5.0.14","recharts":"^3.10.0","react-dom":"19.2.8","tailwindcss":"^4.3.3","tailwind-merge":"^3.6.0","tw-animate-css":"^1.4.0","react-day-picker":"^10.0.1","@tailwindcss/vite":"^4.3.3","@radix-ui/react-slot":"^1.3.1","@radix-ui/react-tabs":"^1.1.19","@radix-ui/react-label":"^2.1.13","@tanstack/react-table":"^8.21.3","@radix-ui/react-dialog":"^1.1.21","@radix-ui/react-select":"^2.3.5","@radix-ui/react-switch":"^1.3.5","@radix-ui/react-popover":"^1.1.21","@radix-ui/react-tooltip":"^1.2.14","class-variance-authority":"^0.7.1"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.1.5","@types/bun":"^1.3.5","typescript":"^5.9.3","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.4"},"_npmOperationalInternal":{"tmp":"tmp/9am-ui_1.1.0_1786725305234_0.9769672506216545","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-08-14T15:54:38.202Z","modified":"2026-08-14T16:56:25.901Z","1.0.0":"2026-08-14T15:54:38.469Z","1.1.0":"2026-08-14T16:35:05.413Z"},"bugs":{"url":"https://github.com/ilovehugetits/9am-ui/issues"},"license":"MIT","homepage":"https://github.com/ilovehugetits/9am-ui#readme","keywords":["fivem","nui","cef","shadcn","shadcn-registry","react","tailwindcss","ui"],"repository":{"url":"git+https://github.com/ilovehugetits/9am-ui.git","type":"git"},"description":"The shared design language, NUI plumbing and FiveM CEF workarounds behind every 9AM Studios script — an open shadcn registry.","maintainers":[{"name":"ata61","email":"caglayanmustafaata@gmail.com"}],"readme":"# 9AM UI\n\nThe shared design language, NUI plumbing and FiveM CEF workarounds behind every 9AM Studios script.\n\nDistributed as a **[shadcn registry](https://ui.shadcn.com/docs/registry)**: components are copied into each script rather than imported from a package, so a script can diverge when it genuinely needs to — while `9am-ui check` makes sure nobody diverges by accident.\n\nExtracted from `9am-vehicleshop` v1.2.8, which is consumer #0.\n\n---\n\n## What's in it\n\n| Layer | Items | What it gives you |\n|---|---|---|\n| **Theme** | `@9am/theme` | OKLCH tokens for both palettes, the `primary-50…950` ramp, radius scale, class-driven `dark:` variant, and the NUI base rules (transparent body, suppressed focus rings, scrollbar utilities). **Locked** — see [Drift policy](#drift-policy). |\n| **Fonts** | `@9am/fonts` | Poppins + Phudu embedded as base64. Kept out of `@9am/theme` on purpose — see [Fonts](#fonts). **Locked.** |\n| **Primitives** | 19 items | `button` (8 variants), `card`, `input`, `label`, `field`, `select`, `multi-select`, `switch`, `separator`, `table`, `data-table`, `tabs`, `dialog`, `popover`, `tooltip`, `info-tip`, `calendar`, `chart`, `viewport` |\n| **Icons** | 47 items | `@9am/icon-*` — hand-built animated SVGs, no icon library dependency. Each exposes `startAnimation()`/`stopAnimation()` through a ref so a parent (a tab, a table row) can drive it. |\n| **NUI** | `@9am/nui`, `@9am/visibility`, `@9am/use-theme`, `@9am/i18n` | `fetchNui`, `useNuiEvent`, `debugData`, browser-dev detection, frame visibility with ESC + focus release, theme store, and runtime i18n pulled from Lua. |\n| **Lib** | `@9am/utils`, `@9am/smooth-scroll` | `cn()`, and the global wheel handler that repairs scrolling in CEF. |\n| **Scaffold** | `@9am/scaffold` + `9am-ui lua` | A whole new script's UI: vite/tsconfig/eslint/postcss, `index.html`, `main.tsx`, starter `App`, plus the Lua side. |\n\nBrowse it all: `bun run preview` → <http://localhost:5173>.\n\n### The two pieces that matter most\n\n**`@9am/viewport`** is the house scroll container: a drag-able custom scrollbar, layered \"liquid glass\" edge blur, and a header that blur-swaps to a sticky copy as you scroll. It also carries the CEF-103 workarounds — `clipPath` instead of `overflow`+radius, stacked fixed-blur bands because `mask` doesn't apply to `backdrop-filter` output, and JS-computed grid columns because `:has()` and `@container` don't exist in Chromium 103.\n\n**`@9am/smooth-scroll`** exists because CEF will not wheel-scroll a `clip-path`'d container at all. Without it, the viewport is unscrollable in-game while working fine in your browser.\n\n---\n\n## Use it in a new script\n\n```bash\nmkdir -p my-script/web && cd my-script/web\nbun init -y\n```\n\nAdd `components.json`:\n\n```jsonc\n{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"new-york\", \"rsc\": false, \"tsx\": true,\n  \"tailwind\": {\n    \"config\": \"\", \"css\": \"src/index.css\",\n    \"baseColor\": \"neutral\", \"cssVariables\": true, \"prefix\": \"\"\n  },\n  \"aliases\": {\n    \"components\": \"@/components\", \"utils\": \"@/lib/utils\",\n    \"ui\": \"@/components/ui\", \"lib\": \"@/lib\", \"hooks\": \"@/hooks\"\n  },\n  \"registries\": {\n    \"@9am\": {\n      \"url\": \"https://raw.githubusercontent.com/ilovehugetits/9am-ui/main/r/{name}.json\"\n    }\n  }\n}\n```\n\nThen:\n\n```bash\nbunx shadcn@latest add @9am/scaffold     # web skeleton + every dependency\ncd .. && bunx 9am-ui lua                 # Lua side, from the resource root\n```\n\n> The CLI is on npm as [`9am-ui`](https://www.npmjs.com/package/9am-ui). Examples\n> use `bunx` because the rest of the kit assumes bun, but `npx 9am-ui` works\n> identically — the published binary is plain ESM with a `node` shebang.\n\nFinally, edit **`web/src/nui.config.ts`** — it is the one kit file you are meant to change:\n\n```ts\nexport const nuiConfig = {\n  resourceName: \"my-script\",\n  themeStorageKey: \"my-script:theme\",\n  defaultTheme: \"dark\",\n}\n```\n\nKeep the `localStorage` key in `index.html` in sync with `themeStorageKey` (it runs before first paint to avoid a theme flash), then:\n\n```bash\ncd web && bun install && bun run build\nbunx 9am-ui doctor    # confirms the registry, theme import and the CEF css setup\n```\n\n## Use it in an existing script\n\nAdd the `registries` block above to your `components.json`, then take what you want:\n\n```bash\nbunx shadcn@latest add @9am/theme @9am/viewport @9am/data-table\n```\n\nTransitive dependencies resolve automatically — `@9am/data-table` pulls `button`, `input`, `table`, `i18n` and its three icons.\n\nAfter adding `@9am/theme`, import it from your entry stylesheet:\n\n```css\n@import \"tailwindcss\";\n@import \"tw-animate-css\";\n@import \"./styles/9am-fonts.css\";   /* or 9am-fonts-linked.css — see below */\n@import \"./styles/9am-theme.css\";\n```\n\n---\n\n## Fonts\n\n`9am-theme.css` deliberately does **not** import a font stylesheet, because which one you want depends on your app:\n\n| | Use when | How |\n|---|---|---|\n| **`@9am/fonts`** (base64) | Single html entry — the common case | `bunx shadcn@latest add @9am/fonts` |\n| **Linked woff2** | Several html entries, especially DUI texture pages | `bunx 9am-ui fonts`, then import `9am-fonts-linked.css` |\n\nEmbedding is the better default: one command, nothing else to fetch, and in a NUI everything is served off local disk so there is no network round-trip to save. It becomes the wrong choice as soon as you have multiple entry points — **every DUI is its own CEF instance**, so each one would decode the entire 322 KB payload again with nothing shared between them.\n\n`9am-vehicleshop` is the worked example: it has three entries (main NUI, phone, showroom stand) and `client/showroom.lua` calls `CreateDui` once per showroom slot, so it uses the linked variant everywhere.\n\n---\n\n## Non-negotiables for CEF\n\nFiveM's CEF is **Chromium 103**. Two things will silently ruin a build:\n\n1. **`postcss.config.js` must keep `postcss-color-converter`.** The tokens are authored in `oklch()`, which CEF cannot parse. Without the conversion the UI renders completely unstyled in-game while looking perfect in `bun run start`. Verify with:\n   ```bash\n   bun run build && grep -c oklch dist/assets/*.css   # must be 0\n   ```\n2. **`installSmoothScroll()` must run in `main.tsx`.** Otherwise nothing scrolls in-game.\n\n`bunx 9am-ui doctor` checks both, including scanning your built CSS for surviving `oklch()`.\n\n---\n\n## Drift policy\n\n```bash\nbunx 9am-ui check     # run from web/, wire it into CI\n```\n\n| What changed | Result |\n|---|---|\n| `src/styles/9am-theme.css` or `9am-fonts.css` | **Fails (exit 1).** Identical tokens are what make the scripts read as siblings. Restore with `bunx shadcn@latest add @9am/theme @9am/fonts --overwrite`, or make the change here and release it. |\n| Any component or icon | **Warns (exit 0).** Allowed — teams need the escape hatch — but a local fix helps nobody else. Consider upstreaming. |\n| `src/nui.config.ts` | Ignored. It is supposed to differ. |\n| Anything from `@9am/scaffold` | Ignored. A starting point, not a managed artifact. |\n\n---\n\n## Releasing a change\n\n```bash\nbun run build       # regenerates fonts, registry.json and r/\nbun run typecheck\nbun run preview     # eyeball it in both themes\ngit commit -am \"feat(button): ...\" && git push\n```\n\n`r/` is committed on purpose — `raw.githubusercontent.com` serves committed files, which is what lets this repo act as a registry with no hosting at all.\n\nConsumers pick the change up on their next `shadcn add ... --overwrite`. Nothing auto-updates; that is deliberate.\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for adding a component.\n\n---\n\n## License\n\n[MIT](./LICENSE). Copy the components into your own scripts freely — that is what a copy-in registry is for.\n\nPoppins and Phudu ship under the [SIL Open Font License 1.1](https://openfontlicense.org/), which travels with them.\n","readmeFilename":"README.md"}