{"_id":"@appboxo/ui-kit","_rev":"4-f0c88821703859e910d2753d38290d5c","name":"@appboxo/ui-kit","dist-tags":{"latest":"0.3.2"},"versions":{"0.2.1":{"name":"@appboxo/ui-kit","version":"0.2.1","keywords":["react","ui-kit","design-system","arco-design","mobile","miniapp","themeable","boxo","freedom"],"license":"UNLICENSED","_id":"@appboxo/ui-kit@0.2.1","maintainers":[{"name":"alenboxo","email":"alen@appboxo.com"},{"name":"rayevk","email":"kani@appboxo.com"}],"homepage":"https://github.com/Appboxo/ui-kit#readme","bugs":{"url":"https://github.com/Appboxo/ui-kit/issues"},"dist":{"shasum":"f34775354347958e481913dff4b84953ca957e10","tarball":"https://registry.npmjs.org/@appboxo/ui-kit/-/ui-kit-0.2.1.tgz","fileCount":229,"integrity":"sha512-rijTXwZ/YgkSLbCVmxOkBAWL21Z6vJ4g5UcPmG9DCRcEMZqb0fFErMgnGomEnpN5qsSOZlvBtarE6vvo3/aM7w==","signatures":[{"sig":"MEYCIQCqfTcie4BGJpQNSV4BUGI0NCfVJGNW/yAgqEJt6ut0dQIhAPH2bULIt/ItbhGd7Wcpmjys/PSbOferIMu/F8BJe8ty","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1488521},"main":"./dist/index.cjs","type":"module","_from":"file:appboxo-ui-kit-0.2.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js","require":"./dist/next.cjs"},"./src/*":"./src/*","./themes/*":"./themes/*","./styles.css":"./dist/index.css","./package.json":"./package.json"},"private":false,"scripts":{"dev":"tsup --watch","build":"pnpm run build:themes && tsup","release":"pnpm run build && changeset publish","version":"changeset version","changeset":"changeset","storybook":"storybook dev -p 6008","typecheck":"tsc --noEmit","test:tokens":"pnpm run build:themes && node scripts/check-token-coverage.mjs","build:themes":"node scripts/build-themes.mjs","build-storybook":"storybook build"},"_npmUser":{"name":"alenboxo","email":"alen@appboxo.com"},"_resolved":"/private/var/folders/pw/11fdchh9365f855bvxxv40rr0000gn/T/2e9afb09f38f07b1d45c0057571516db/appboxo-ui-kit-0.2.1.tgz","_integrity":"sha512-rijTXwZ/YgkSLbCVmxOkBAWL21Z6vJ4g5UcPmG9DCRcEMZqb0fFErMgnGomEnpN5qsSOZlvBtarE6vvo3/aM7w==","repository":{"url":"git+https://github.com/Appboxo/ui-kit.git","type":"git"},"_npmVersion":"11.6.2","description":"A themeable, host-agnostic React UI kit for Boxo and partner mini-apps.","directories":{},"sideEffects":["*.css","*.less"],"_nodeVersion":"25.2.0","dependencies":{"mime":"^4.0.4","ahooks":"^3.8.0","date-fns":"^3.6.0","lodash-es":"^4.17.21","framer-motion":"^11.1.9","@emotion/react":"^11.13.3","react-markdown":"^9.0.1","compare-versions":"^6.1.0","react-responsive":"^10.0.1","libphonenumber-js":"^1.11.17","react-device-detect":"^2.2.3","react-awesome-reveal":"^4.2.14","react-copy-to-clipboard":"^5.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"less":"^4.2.0","tsup":"^8.3.0","vite":"^5.4.0","tslib":"^2.6.3","storybook":"8.6.15","@svgr/core":"^8.1.0","typescript":"^5.5.4","@types/node":"^20","@types/react":"^18.3.3","@changesets/cli":"^2.31.0","@storybook/react":"8.6.15","@svgr/plugin-jsx":"^8.1.0","@types/lodash-es":"^4.17.12","@storybook/blocks":"8.6.15","@storybook/theming":"8.6.15","@storybook/react-vite":"8.6.15","@storybook/manager-api":"8.6.15","@storybook/addon-essentials":"8.6.15","@changesets/changelog-github":"^0.7.0","typescript-plugin-css-modules":"^5.1.0","@types/react-copy-to-clipboard":"^5.0.7"},"peerDependencies":{"next":"^14","react":"^18","react-dom":"^18","next-i18next":"^15","@tanstack/react-query":"^5","@arco-design/mobile-react":"^2.34","@arco-design/mobile-utils":"^2.20"},"_npmOperationalInternal":{"tmp":"tmp/ui-kit_0.2.1_1779688557699_0.9958969263802233","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@appboxo/ui-kit","version":"0.3.0","keywords":["react","ui-kit","design-system","arco-design","mobile","miniapp","themeable","boxo","freedom"],"license":"UNLICENSED","_id":"@appboxo/ui-kit@0.3.0","maintainers":[{"name":"alenboxo","email":"alen@appboxo.com"},{"name":"rayevk","email":"kani@appboxo.com"}],"homepage":"https://github.com/Appboxo/ui-kit#readme","bugs":{"url":"https://github.com/Appboxo/ui-kit/issues"},"dist":{"shasum":"e087008da2f883da82c0d0e08973fe76f52b1d35","tarball":"https://registry.npmjs.org/@appboxo/ui-kit/-/ui-kit-0.3.0.tgz","fileCount":236,"integrity":"sha512-dMkkrRufQF6rYjzFabqQjxcGWrf15QqwcjF5h4G4qui36gfKMwrXZrMFQq0qJqj3Rmmb+bR5SUVSQutZv2TN9g==","signatures":[{"sig":"MEYCIQC8RSSNQdoZyiDbcdrow6WvnK/QWIVZUHevn4tfFtDaoAIhAJV3xYx+95ijLl1gvALD4GBC5KqZ2W5NPI3wgFXLrfN5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1838022},"main":"./dist/index.cjs","type":"module","_from":"file:appboxo-ui-kit-0.3.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js","require":"./dist/next.cjs"},"./src/*":"./src/*","./themes/*":"./themes/*","./styles.css":"./dist/index.css","./package.json":"./package.json"},"private":false,"scripts":{"dev":"tsup --watch","build":"pnpm run build:themes && pnpm run build:arco-css && tsup","release":"pnpm run build && changeset publish","version":"changeset version","changeset":"changeset","storybook":"storybook dev -p 6008","typecheck":"tsc --noEmit","test:tokens":"pnpm run build:themes && node scripts/check-token-coverage.mjs","build:themes":"node scripts/build-themes.mjs","build:arco-css":"node scripts/build-arco-mobile-css.mjs","build-storybook":"storybook build"},"_npmUser":{"name":"alenboxo","email":"alen@appboxo.com"},"_resolved":"/private/var/folders/pw/11fdchh9365f855bvxxv40rr0000gn/T/d893e5c80e62ac573fdad849808e8f34/appboxo-ui-kit-0.3.0.tgz","_integrity":"sha512-dMkkrRufQF6rYjzFabqQjxcGWrf15QqwcjF5h4G4qui36gfKMwrXZrMFQq0qJqj3Rmmb+bR5SUVSQutZv2TN9g==","repository":{"url":"git+https://github.com/Appboxo/ui-kit.git","type":"git"},"_npmVersion":"11.6.2","description":"A themeable, host-agnostic React UI kit for Boxo and partner mini-apps.","directories":{},"sideEffects":["*.css","*.less"],"_nodeVersion":"25.2.0","dependencies":{"mime":"^4.0.4","ahooks":"^3.8.0","date-fns":"^3.6.0","lodash-es":"^4.17.21","framer-motion":"^11.1.9","@emotion/react":"^11.13.3","react-markdown":"^9.0.1","compare-versions":"^6.1.0","react-responsive":"^10.0.1","libphonenumber-js":"^1.11.17","react-device-detect":"^2.2.3","react-awesome-reveal":"^4.2.14","react-copy-to-clipboard":"^5.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"less":"^4.2.0","tsup":"^8.3.0","vite":"^5.4.0","tslib":"^2.6.3","rollup":"^4.60.4","postcss":"^8.5.15","storybook":"8.6.15","@svgr/core":"^8.1.0","typescript":"^5.5.4","@types/node":"^20","@types/react":"^18.3.3","@changesets/cli":"^2.31.0","@storybook/react":"8.6.15","@svgr/plugin-jsx":"^8.1.0","@types/lodash-es":"^4.17.12","@storybook/blocks":"8.6.15","@storybook/theming":"8.6.15","@storybook/react-vite":"8.6.15","rollup-plugin-postcss":"^4.0.2","@storybook/manager-api":"8.6.15","less-plugin-npm-import":"^2.1.0","@rollup/plugin-node-resolve":"^16.0.3","@storybook/addon-essentials":"8.6.15","@changesets/changelog-github":"^0.7.0","typescript-plugin-css-modules":"^5.1.0","@types/react-copy-to-clipboard":"^5.0.7"},"peerDependencies":{"next":"^14","react":"^18","react-dom":"^18","next-i18next":"^15","@tanstack/react-query":"^5","@arco-design/mobile-react":"^2.34","@arco-design/mobile-utils":"^2.20"},"_npmOperationalInternal":{"tmp":"tmp/ui-kit_0.3.0_1779874798385_0.5065508747188527","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@appboxo/ui-kit","version":"0.3.1","keywords":["react","ui-kit","design-system","arco-design","mobile","miniapp","themeable","boxo","freedom"],"license":"UNLICENSED","_id":"@appboxo/ui-kit@0.3.1","maintainers":[{"name":"alenboxo","email":"alen@appboxo.com"},{"name":"rayevk","email":"kani@appboxo.com"}],"homepage":"https://github.com/Appboxo/ui-kit#readme","bugs":{"url":"https://github.com/Appboxo/ui-kit/issues"},"dist":{"shasum":"f7aa7236786df9d0aba1935b14ed9883920a968b","tarball":"https://registry.npmjs.org/@appboxo/ui-kit/-/ui-kit-0.3.1.tgz","fileCount":236,"integrity":"sha512-FLfzdhEc5OGNKlvdTwV7F5rEbNFJTAXELezJKBlWfTrzlUsTAGwxl5tSCAerd6EXZk4/6q65K5C9AkNq4EhUdA==","signatures":[{"sig":"MEYCIQCIF3ZX1QD8IZYr1cLFohFskWwE69TNbJBRLKyPmhc3LQIhAJ2MwmZwcAoY1C9g17Z0z+xhlsteyyJ85XUFE3bY+WQF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1839190},"main":"./dist/index.cjs","type":"module","_from":"file:appboxo-ui-kit-0.3.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js","require":"./dist/next.cjs"},"./src/*":"./src/*","./themes/*":"./themes/*","./styles.css":"./dist/index.css","./package.json":"./package.json"},"private":false,"scripts":{"dev":"tsup --watch","build":"pnpm run build:themes && pnpm run build:arco-css && tsup","release":"pnpm run build && changeset publish","version":"changeset version","changeset":"changeset","storybook":"storybook dev -p 6008","typecheck":"tsc --noEmit","test:tokens":"pnpm run build:themes && node scripts/check-token-coverage.mjs","build:themes":"node scripts/build-themes.mjs","build:arco-css":"node scripts/build-arco-mobile-css.mjs","build-storybook":"storybook build"},"_npmUser":{"name":"alenboxo","email":"alen@appboxo.com"},"_resolved":"/private/var/folders/pw/11fdchh9365f855bvxxv40rr0000gn/T/a0a5d5da01cb848de305d926cc3bd360/appboxo-ui-kit-0.3.1.tgz","_integrity":"sha512-FLfzdhEc5OGNKlvdTwV7F5rEbNFJTAXELezJKBlWfTrzlUsTAGwxl5tSCAerd6EXZk4/6q65K5C9AkNq4EhUdA==","repository":{"url":"git+https://github.com/Appboxo/ui-kit.git","type":"git"},"_npmVersion":"11.6.2","description":"A themeable, host-agnostic React UI kit for Boxo and partner mini-apps.","directories":{},"sideEffects":["*.css","*.less"],"_nodeVersion":"25.2.0","dependencies":{"mime":"^4.0.4","ahooks":"^3.8.0","date-fns":"^3.6.0","lodash-es":"^4.17.21","framer-motion":"^11.1.9","@emotion/react":"^11.13.3","react-markdown":"^9.0.1","compare-versions":"^6.1.0","react-responsive":"^10.0.1","libphonenumber-js":"^1.11.17","react-device-detect":"^2.2.3","react-awesome-reveal":"^4.2.14","react-copy-to-clipboard":"^5.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"less":"^4.2.0","tsup":"^8.3.0","vite":"^5.4.0","tslib":"^2.6.3","rollup":"^4.60.4","postcss":"^8.5.15","storybook":"8.6.15","@svgr/core":"^8.1.0","typescript":"^5.5.4","@types/node":"^20","@types/react":"^18.3.3","@changesets/cli":"^2.31.0","@storybook/react":"8.6.15","@svgr/plugin-jsx":"^8.1.0","@types/lodash-es":"^4.17.12","@storybook/blocks":"8.6.15","@storybook/theming":"8.6.15","@storybook/react-vite":"8.6.15","rollup-plugin-postcss":"^4.0.2","@storybook/manager-api":"8.6.15","less-plugin-npm-import":"^2.1.0","@rollup/plugin-node-resolve":"^16.0.3","@storybook/addon-essentials":"8.6.15","@changesets/changelog-github":"^0.7.0","typescript-plugin-css-modules":"^5.1.0","@types/react-copy-to-clipboard":"^5.0.7"},"peerDependencies":{"next":"^14","react":"^18","react-dom":"^18","next-i18next":"^15","@tanstack/react-query":"^5","@arco-design/mobile-react":"^2.34","@arco-design/mobile-utils":"^2.20"},"_npmOperationalInternal":{"tmp":"tmp/ui-kit_0.3.1_1779953442674_0.6483332966434674","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@appboxo/ui-kit","version":"0.3.2","description":"A themeable, host-agnostic React UI kit for Boxo and partner mini-apps.","license":"UNLICENSED","private":false,"sideEffects":["*.css","*.less"],"repository":{"type":"git","url":"git+https://github.com/Appboxo/ui-kit.git"},"homepage":"https://github.com/Appboxo/ui-kit#readme","bugs":{"url":"https://github.com/Appboxo/ui-kit/issues"},"keywords":["react","ui-kit","design-system","arco-design","mobile","miniapp","themeable","boxo","freedom"],"engines":{"node":">=18"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js","require":"./dist/next.cjs"},"./styles.css":"./dist/index.css","./themes/*":"./themes/*","./src/*":"./src/*","./package.json":"./package.json"},"peerDependencies":{"@arco-design/mobile-react":"^2.34","@arco-design/mobile-utils":"^2.20","@tanstack/react-query":"^5","next":"^14","next-i18next":"^15","react":"^18","react-dom":"^18"},"dependencies":{"@emotion/react":"^11.13.3","ahooks":"^3.8.0","compare-versions":"^6.1.0","date-fns":"^3.6.0","framer-motion":"^11.1.9","libphonenumber-js":"^1.11.17","lodash-es":"^4.17.21","mime":"^4.0.4","react-awesome-reveal":"^4.2.14","react-copy-to-clipboard":"^5.1.0","react-device-detect":"^2.2.3","react-markdown":"^9.0.1","react-responsive":"^10.0.1"},"devDependencies":{"@changesets/changelog-github":"^0.7.0","@changesets/cli":"^2.31.0","@rollup/plugin-node-resolve":"^16.0.3","@storybook/addon-essentials":"8.6.15","@storybook/blocks":"8.6.15","@storybook/manager-api":"8.6.15","@storybook/react":"8.6.15","@storybook/react-vite":"8.6.15","@storybook/theming":"8.6.15","@svgr/core":"^8.1.0","@svgr/plugin-jsx":"^8.1.0","@types/lodash-es":"^4.17.12","@types/node":"^20","@types/react":"^18.3.3","@types/react-copy-to-clipboard":"^5.0.7","less":"^4.2.0","less-plugin-npm-import":"^2.1.0","postcss":"^8.5.15","rollup":"^4.60.4","rollup-plugin-postcss":"^4.0.2","storybook":"8.6.15","tslib":"^2.6.3","tsup":"^8.3.0","typescript":"^5.5.4","typescript-plugin-css-modules":"^5.1.0","vite":"^5.4.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"pnpm run build:themes && pnpm run build:arco-css && tsup","build:themes":"node scripts/build-themes.mjs","build:arco-css":"node scripts/build-arco-mobile-css.mjs","dev":"tsup --watch","typecheck":"tsc --noEmit","test:tokens":"pnpm run build:themes && node scripts/check-token-coverage.mjs","storybook":"storybook dev -p 6008","build-storybook":"storybook build","changeset":"changeset","version":"changeset version","release":"pnpm run build && changeset publish"},"_id":"@appboxo/ui-kit@0.3.2","_integrity":"sha512-Rn83/CorejnEn2gm0iP9I/qtca3PKxlnWCozwSU1UW/W2QMNuokdJEBRHntcRDBvcTIUaQK7Cl8vK+uIA/EaCg==","_resolved":"/private/var/folders/pw/11fdchh9365f855bvxxv40rr0000gn/T/cce4138b8db6b9818af45a643bf187aa/appboxo-ui-kit-0.3.2.tgz","_from":"file:appboxo-ui-kit-0.3.2.tgz","_nodeVersion":"25.2.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-Rn83/CorejnEn2gm0iP9I/qtca3PKxlnWCozwSU1UW/W2QMNuokdJEBRHntcRDBvcTIUaQK7Cl8vK+uIA/EaCg==","shasum":"f341eec5efeb30205b0e1bcd6e77e4d9bf385fb8","tarball":"https://registry.npmjs.org/@appboxo/ui-kit/-/ui-kit-0.3.2.tgz","fileCount":236,"unpackedSize":1840993,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHyzKHUgQaklLEhqwqRh3C6LJLwZm2kZ4Wh2BdSQYy+jAiA1IXLmLpjURhMzQQmk/imbautuB1uPP9TSsiV8Mhjq7w=="}]},"_npmUser":{"name":"alenboxo","email":"alen@appboxo.com"},"directories":{},"maintainers":[{"name":"alenboxo","email":"alen@appboxo.com"},{"name":"rayevk","email":"kani@appboxo.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ui-kit_0.3.2_1779958989987_0.0807920201780441"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-25T05:55:57.496Z","modified":"2026-05-28T09:03:10.345Z","0.2.1":"2026-05-25T05:55:57.857Z","0.3.0":"2026-05-27T09:39:58.598Z","0.3.1":"2026-05-28T07:30:42.881Z","0.3.2":"2026-05-28T09:03:10.179Z"},"bugs":{"url":"https://github.com/Appboxo/ui-kit/issues"},"license":"UNLICENSED","homepage":"https://github.com/Appboxo/ui-kit#readme","keywords":["react","ui-kit","design-system","arco-design","mobile","miniapp","themeable","boxo","freedom"],"repository":{"type":"git","url":"git+https://github.com/Appboxo/ui-kit.git"},"description":"A themeable, host-agnostic React UI kit for Boxo and partner mini-apps.","maintainers":[{"name":"alenboxo","email":"alen@appboxo.com"},{"name":"rayevk","email":"kani@appboxo.com"}],"readme":"# @appboxo/ui-kit\n\n> A themeable, host-agnostic React UI kit for Boxo and partner mini-apps.\n\n`@appboxo/ui-kit` is the design system distilled out of the Boxo mini-apps\nmonorepo: typography, layout primitives, form controls and surfaces — all\nthemeable through CSS custom properties.\n\nIt is intentionally **host-agnostic**: the kit doesn't know whether it runs\ninside a Telegram WebApp, a Boxo native shell, or a plain browser. Anything\nhost-specific (haptic feedback, native share, …) is plugged in by the\nconsuming app at startup.\n\n## Status\n\nCurrently at `0.2`. API is stabilizing. We are dogfooding the kit by\nwhite-labeling internal apps before opening it up to external teams.\n\n## Install\n\n```bash\npnpm add @appboxo/ui-kit\n\n# Peer dependencies you need in your app\npnpm add react react-dom react-i18next i18next \\\n         @arco-design/mobile-react @arco-design/mobile-utils \\\n         @tanstack/react-query\n\n# Next.js apps additionally need:\npnpm add next next-i18next\n```\n\n## Quick start\n\n```tsx\n// _app.tsx (Next) or main.tsx (Vite)\nimport \"@arco-design/mobile-react/esm/style\";\n// Kit's component-local stylesheets (Tip icon sizing, Card padding,\n// Input borders, etc.). Bundled at build time; import once at entry.\nimport \"@appboxo/ui-kit/styles.css\";\n// Brand theme. Pre-compiled CSS, no Less pipeline required.\nimport \"@appboxo/ui-kit/themes/freedom/theme.css\";\n\nimport {\n  PrimaryButton,\n  Card,\n  Body1,\n  Flex,\n  setHapticHandler,\n} from \"@appboxo/ui-kit\";\n\n// Optional: wire up host capabilities once at startup\nsetHapticHandler((style) => navigator.vibrate?.(style === \"heavy\" ? 20 : 10));\n\nexport default function Home() {\n  return (\n    <Flex vertical gap={16}>\n      <Card>\n        <Body1>Welcome</Body1>\n      </Card>\n      <PrimaryButton text=\"Continue\" onClick={() => console.log(\"clicked\")} />\n    </Flex>\n  );\n}\n```\n\nA full runnable example lives in [`examples/basic-app`](./examples/basic-app).\n\n## Providers (real apps)\n\nThe snippet above is enough for static screens, but a real app usually wants\nReact Query and a place to compose context providers. The kit ships\n`MultiProvider` and `QueryProvider` for that:\n\n```tsx\nimport { MultiProvider, QueryProvider } from \"@appboxo/ui-kit\";\nimport { QueryClient } from \"@tanstack/react-query\";\n\nconst queryClient = new QueryClient();\n\nconst providers = [\n  <QueryProvider queryClient={queryClient} />,\n  // <YourAuthProvider />, <YourTrackingProvider />, ...\n];\n\nexport default function App({ children }: { children: React.ReactNode }) {\n  return <MultiProvider providers={providers}>{children}</MultiProvider>;\n}\n```\n\nFor a complete wiring (Arco `ContextProvider`, dark-mode resolution, status\nbar colors, …) see\n[`examples/pass-freedom/src/lib/with-providers.tsx`](./examples/pass-freedom/src/lib/with-providers.tsx).\n\n## Theming\n\nTheming is done entirely through CSS custom properties. The kit ships\n**37 themes**:\n\n- `themes/default/` — brand-neutral baseline. Declares every required token\n  with safe defaults (iOS system-blue primary).\n- `themes/freedom/`, `themes/snoonu/`, `themes/telegram/`, … — 36 partner\n  brands carried over from the historical `boxo-miniapps/packages/esim-theme/`\n  via `scripts/migrate-esim-theme.mjs`. Each one extends `default/` and\n  re-declares only the tokens that differ.\n\nToggle between brands at runtime with the **Brand** dropdown in Storybook\nor in [`examples/kitchen-sink`](./examples/kitchen-sink) (a single-page\ngallery that renders every component under whichever brand you pick),\nor import the one you want directly.\n\nTwo integration patterns, depending on how much you want to control:\n\n```ts\n// 1. \"I am Freedom\" -- use the bundled brand.\nimport \"@appboxo/ui-kit/themes/freedom/theme.css\";\n\n// 2. \"I am another brand, light overlay\" -- recommended for partners.\n//    Pull in the neutral baseline, then override only what differs.\nimport \"@appboxo/ui-kit/themes/default/theme.css\";\nimport \"@/styles/my-brand.css\"; // declares e.g. `#root { --primary-6: #ff7a00; }`\n```\n\n`pnpm test:tokens` validates that the kit's components only read tokens that\nthe default theme actually declares — useful as a regression check when you\nadd new components.\n\nSee [`themes/README.md`](./themes/README.md) for the full token contract,\ndark-mode notes, and the \"adding a new brand\" recipe.\n\n## Host integration\n\nSome components want host capabilities the kit can't provide on its own.\nPlug them in once at startup:\n\n```ts\nimport {\n  setHapticHandler,\n  setShareFileHandler,\n} from \"@appboxo/ui-kit\";\n\nsetHapticHandler((style) => myHost.haptic(style));\nsetShareFileHandler(async (url, name) => myHost.share({ url, name }));\n```\n\nDefaults are no-ops, so the kit works without any wiring.\n\n## What's included\n\n| Group | Components |\n|---|---|\n| Typography | `LargeTitle`, `Title1`–`Title3`, `Headline`, `Body1`, `Body2`, `Callout`, `Footnote1`, `Footnote2`, `Caption1`–`Caption3` |\n| Layout | `Layout`, `ResponsiveLayout`, `Flex`, `Footer`, `LayoutLoading` |\n| Forms | `Input`, `Textarea`, `Checkbox`, `Radio`, `SearchBar`, `PickerInput`, `DatePicker`, `TimePicker`, `DialCodeSelector` |\n| Surfaces | `Card`, `Drawer`, `PopupSwiper`, `Tip`, `Toast`, `Placeholder` |\n| Display | `Tabs`, `TouchCell`, `SummaryTable`, `Markdown`, `Copyable` |\n| Buttons | `PrimaryButton`, `SecondaryButton`, `TertiaryButton`, `QuaternaryButton` |\n| Providers | `MultiProvider`, `QueryProvider` |\n| Hooks | `useDevice`, `useBreakpoint`, `useDesktopDetection`, `useSafeArea`, `useScrollTop`, `useDarkMode`, … |\n\nStorybook is deployed (Boxo-themed):\n<https://ui-kit-ofey.vercel.app/?path=/docs/introduction--docs>\n\nTo run it locally:\n\n```bash\npnpm storybook\n```\n\n## Examples\n\n```\nexamples/\n├── basic-app/           # 70-line \"hello world\" -- absolute minimum kit consumer,\n│                        # via workspace `file:../..` (workspace-style).\n├── with-npm-quickstart/ # Same shape as basic-app, but pulls the kit\n│                        # from the public npm registry instead of the\n│                        # workspace. Use this one to validate the\n│                        # *publish pipeline*, not the design.\n├── freedom-theme/      # Paired example A: identical app rendered with the\n│                       # bundled `themes/freedom/theme.css`.\n├── custom-theme/       # Paired example B: same App.tsx, swapped for the\n│                       # neutral `default/theme.css` + a tiny `my-brand.css`\n│                       # overlay (fictional Citrus brand). `diff -r` against\n│                       # `freedom-theme/` shows EXACTLY what BYO theming costs.\n├── kitchen-sink/       # Single-page kit gallery: every component on one\n│                       # page with a brand toolbar (37 themes) + light/dark\n│                       # toggle. Faster than Storybook for \"what does\n│                       # brand X look like across the whole UI?\" reviews.\n└── pass-freedom/       # A full real-world mini-app (forked from production\n                        # pass-freedom). 11 pages, all backend / host calls\n                        # replaced with mocks. Useful as a soak test for the kit.\n```\n\nTo compare bundled vs. BYO theme side-by-side (recommended for partner onboarding):\n\n```bash\npnpm install && pnpm build           # build the kit dist/\n\ncd examples/freedom-theme && pnpm install && pnpm dev   # http://localhost:5173\n\n# in another terminal\ncd examples/custom-theme  && pnpm install && pnpm dev   # http://localhost:5174\n\ndiff -r examples/freedom-theme examples/custom-theme    # see the BYO touchpoints\n```\n\nTo run the kitchen sink (recommended for design / brand review):\n\n```bash\npnpm install && pnpm build\ncd examples/kitchen-sink\npnpm install\npnpm dev                  # http://localhost:5173\n```\n\nTo run the full pass-freedom demo:\n\n```bash\npnpm install && pnpm build\ncd examples/pass-freedom\npnpm install\npnpm dev                  # http://localhost:3000\n```\n\n## Repository layout\n\n```\nsrc/         The kit source — components, hooks, theming entry points\nthemes/      Brand themes. `default/` is the brand-neutral baseline,\n             `freedom/` is the example brand built on top of it.\n             Each ships both .less (source) and .css (pre-compiled,\n             generated by `pnpm build:themes`). Copy `freedom/` to\n             scaffold a new brand.\nscripts/     Build-time helpers: `build-themes.mjs` (.less → .css) and\n             `check-token-coverage.mjs` (theme contract test).\n.storybook/  Storybook config\nexamples/    Runnable consumer apps (start with examples/basic-app)\n```\n\n## Development\n\n```bash\npnpm install\npnpm storybook        # local Storybook on :6008\npnpm build            # build:themes → tsup → dist/\npnpm build:themes     # compile themes/*/theme.less → theme.css\npnpm test:tokens      # verify default theme covers every required token\npnpm typecheck        # tsc --noEmit\n```\n\n## Why this kit exists\n\nBoxo runs more than forty white-labeled mini-apps. Most share the same\nfundamentals — typography, spacing, form patterns, eSIM-like flows — but\ndiverge wildly on brand visuals.\n\nThe kit is the small, opinionated layer those apps agree on: a token system\nthat any brand can override, a typography scale that survives the redesign\ncycle, and a handful of primitives (Flex, Card, Input, …) that are useful\nwithout being prescriptive.\n\nIt is not a replacement for Arco Mobile — it sits on top of it.\n\n## License\n\nInternal — Boxo / Appboxo.\n","readmeFilename":"README.md"}