{"_id":"@adore96/ui-kit","_rev":"3-9457adbf0cf6303d10e022b7aff2c381","name":"@adore96/ui-kit","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@adore96/ui-kit","version":"0.1.0","keywords":["neurocore","ui-kit","react","components","hooks","zustand","tanstack-query","radix-ui","zod","tailwind"],"author":{"name":"Neurocore Team"},"license":"MIT","_id":"@adore96/ui-kit@0.1.0","maintainers":[{"name":"adore96","email":"adorekasun@gmail.com"}],"homepage":"https://bitbucket.org/aldi-workspace/neurocore-ui-kit#readme","bugs":{"url":"https://bitbucket.org/aldi-workspace/neurocore-ui-kit/issues"},"dist":{"shasum":"ce5670a062de4b0897274467beba7b0874b0e64a","tarball":"https://registry.npmjs.org/@adore96/ui-kit/-/ui-kit-0.1.0.tgz","fileCount":99,"integrity":"sha512-dmJILRWqd3gkols+6qnCDvtUaEQAkRpP0Tf8cmDiRXLUO2f0aTIxsk6dquJ7WpVZizHEHXYBDigB9dWWhunCBQ==","signatures":[{"sig":"MEUCIQCq1QwlTtcGmyA4pte8bXtsB47Tn2+iCbYJoobNFMUb2gIgT7UAndlxzdwojA7EWq186CTpKALZhPVGucjQzLkWkH0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":6245805},"main":"./dist/index.cjs","type":"module","_from":"file:adore96-ui-kit-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dto":{"types":"./dist/dto/index.d.ts","import":"./dist/dto/index.js","require":"./dist/dto/index.cjs"},"./lib":{"types":"./dist/lib/index.d.ts","import":"./dist/lib/index.js","require":"./dist/lib/index.cjs"},"./hooks":{"types":"./dist/hooks/index.d.ts","import":"./dist/hooks/index.js","require":"./dist/hooks/index.cjs"},"./stores":{"types":"./dist/stores/index.d.ts","import":"./dist/stores/index.js","require":"./dist/stores/index.cjs"},"./helpers":{"types":"./dist/helpers/index.d.ts","import":"./dist/helpers/index.js","require":"./dist/helpers/index.cjs"},"./contexts":{"types":"./dist/contexts/index.d.ts","import":"./dist/contexts/index.js","require":"./dist/contexts/index.cjs"},"./services":{"types":"./dist/services/index.d.ts","import":"./dist/services/index.js","require":"./dist/services/index.cjs"},"./constants":{"types":"./dist/constants/index.d.ts","import":"./dist/constants/index.js","require":"./dist/constants/index.cjs"},"./utilities":{"types":"./dist/utilities/index.d.ts","import":"./dist/utilities/index.js","require":"./dist/utilities/index.cjs"},"./components":{"types":"./dist/components/index.d.ts","import":"./dist/components/index.js","require":"./dist/components/index.cjs"},"./validations":{"types":"./dist/validations/index.d.ts","import":"./dist/validations/index.js","require":"./dist/validations/index.cjs"},"./declarations":{"types":"./dist/declarations/index.d.ts","import":"./dist/declarations/index.js","require":"./dist/declarations/index.cjs"}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"tsup","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","typecheck":"tsc --noEmit","build:watch":"tsup --watch","test:publish":"pnpm pack"},"_npmUser":{"name":"adore96","email":"adorekasun@gmail.com"},"_resolved":"C:\\Users\\kasun\\AppData\\Local\\Temp\\2044f23b33bfe17571a9a117aa6353bd\\adore96-ui-kit-0.1.0.tgz","_integrity":"sha512-dmJILRWqd3gkols+6qnCDvtUaEQAkRpP0Tf8cmDiRXLUO2f0aTIxsk6dquJ7WpVZizHEHXYBDigB9dWWhunCBQ==","repository":{"url":"git+https://bitbucket.org/aldi-workspace/neurocore-ui-kit.git","type":"git"},"_npmVersion":"11.9.0","description":"Framework-agnostic UI kit: components, hooks, utilities, stores, DTOs, and validations extracted from neurocore-framework-fe.","directories":{},"sideEffects":false,"_nodeVersion":"24.14.0","dependencies":{"pubnub":"^10.2.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.4.0","typescript":"^5.8.3","@types/node":"^20.0.0","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"zod":">=3.0.0","clsx":">=2.0.0","cmdk":">=1.0.0","axios":">=1.0.0","react":">=19.0.0","motion":">=10.0.0","zustand":">=4.0.0","date-fns":">=4.0.0","recharts":">=2.0.0","react-dom":">=19.0.0","lucide-react":">=0.400.0","tailwind-merge":">=3.0.0","react-hook-form":">=7.0.0","react-hot-toast":">=2.0.0","react-day-picker":">=9.0.0","@hookform/resolvers":">=5.0.0","@radix-ui/react-slot":">=1.2.0","@radix-ui/react-tabs":">=1.1.0","@radix-ui/react-label":">=2.1.0","@tanstack/react-query":">=5.0.0","@tanstack/react-table":">=8.0.0","@radix-ui/react-avatar":">=1.1.0","@radix-ui/react-dialog":">=1.1.0","@radix-ui/react-select":">=2.1.0","@radix-ui/react-switch":">=1.1.0","@radix-ui/react-popover":">=1.1.0","@radix-ui/react-tooltip":">=1.2.0","@radix-ui/react-checkbox":">=1.1.0","@radix-ui/react-progress":">=1.1.0","class-variance-authority":">=0.7.0","currency-code-symbol-map":">=3.0.0","@radix-ui/react-accordion":">=1.2.0","@radix-ui/react-separator":">=1.1.0","@radix-ui/react-collapsible":">=1.1.0","@radix-ui/react-radio-group":">=1.2.0","@radix-ui/react-dropdown-menu":">=2.1.0","@tanstack/react-query-devtools":">=5.0.0"},"peerDependenciesMeta":{"@tanstack/react-query-devtools":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ui-kit_0.1.0_1773934997556_0.49294782637382917","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@adore96/ui-kit","version":"0.1.1","keywords":["neurocore","ui-kit","react","components","hooks","zustand","tanstack-query","radix-ui","zod","tailwind"],"author":{"name":"Neurocore Team"},"license":"MIT","_id":"@adore96/ui-kit@0.1.1","maintainers":[{"name":"adore96","email":"adorekasun@gmail.com"}],"dist":{"shasum":"d7c22d222c7f3fab42febd08f7cedb0802a5009a","tarball":"https://registry.npmjs.org/@adore96/ui-kit/-/ui-kit-0.1.1.tgz","fileCount":99,"integrity":"sha512-Ja1l8C1PABIGSei79yaLHRozk2o+TOa7Vf3cLnB78WfJ8GJONHJmQPu09I3QWOeu+/E9akE0VStEJ8nz8HE9gA==","signatures":[{"sig":"MEYCIQCEcaaALTSmxP+9nOvjBIUwIVNwIhndSUrV4f8QbHYCCAIhAKgy8DnJp9+WICJsGGn2vi0GwQyJKi65tkkqWRIKRNFt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":6245748},"main":"./dist/index.cjs","type":"module","_from":"file:adore96-ui-kit-0.1.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dto":{"types":"./dist/dto/index.d.ts","import":"./dist/dto/index.js","require":"./dist/dto/index.cjs"},"./lib":{"types":"./dist/lib/index.d.ts","import":"./dist/lib/index.js","require":"./dist/lib/index.cjs"},"./hooks":{"types":"./dist/hooks/index.d.ts","import":"./dist/hooks/index.js","require":"./dist/hooks/index.cjs"},"./stores":{"types":"./dist/stores/index.d.ts","import":"./dist/stores/index.js","require":"./dist/stores/index.cjs"},"./helpers":{"types":"./dist/helpers/index.d.ts","import":"./dist/helpers/index.js","require":"./dist/helpers/index.cjs"},"./contexts":{"types":"./dist/contexts/index.d.ts","import":"./dist/contexts/index.js","require":"./dist/contexts/index.cjs"},"./services":{"types":"./dist/services/index.d.ts","import":"./dist/services/index.js","require":"./dist/services/index.cjs"},"./constants":{"types":"./dist/constants/index.d.ts","import":"./dist/constants/index.js","require":"./dist/constants/index.cjs"},"./utilities":{"types":"./dist/utilities/index.d.ts","import":"./dist/utilities/index.js","require":"./dist/utilities/index.cjs"},"./components":{"types":"./dist/components/index.d.ts","import":"./dist/components/index.js","require":"./dist/components/index.cjs"},"./validations":{"types":"./dist/validations/index.d.ts","import":"./dist/validations/index.js","require":"./dist/validations/index.cjs"},"./declarations":{"types":"./dist/declarations/index.d.ts","import":"./dist/declarations/index.js","require":"./dist/declarations/index.cjs"}},"scripts":{"lint":"eslint src --ext .ts,.tsx","build":"tsup","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","typecheck":"tsc --noEmit","build:watch":"tsup --watch","test:publish":"pnpm pack"},"_npmUser":{"name":"adore96","email":"adorekasun@gmail.com"},"_resolved":"C:\\Users\\kasun\\AppData\\Local\\Temp\\e5aa597b7a6b0f1fd822319c815c1f5d\\adore96-ui-kit-0.1.1.tgz","_integrity":"sha512-Ja1l8C1PABIGSei79yaLHRozk2o+TOa7Vf3cLnB78WfJ8GJONHJmQPu09I3QWOeu+/E9akE0VStEJ8nz8HE9gA==","repository":{"url":"","type":"git"},"_npmVersion":"11.9.0","description":"Framework-agnostic UI kit: components, hooks, utilities, stores, DTOs, and validations extracted from neurocore-framework-fe.","directories":{},"sideEffects":false,"_nodeVersion":"24.14.0","dependencies":{"pubnub":"^10.2.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.4.0","typescript":"^5.8.3","@types/node":"^20.0.0","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"zod":">=3.0.0","clsx":">=2.0.0","cmdk":">=1.0.0","axios":">=1.0.0","react":">=19.0.0","motion":">=10.0.0","zustand":">=4.0.0","date-fns":">=4.0.0","recharts":">=2.0.0","react-dom":">=19.0.0","lucide-react":">=0.400.0","tailwind-merge":">=3.0.0","react-hook-form":">=7.0.0","react-hot-toast":">=2.0.0","react-day-picker":">=9.0.0","@hookform/resolvers":">=5.0.0","@radix-ui/react-slot":">=1.2.0","@radix-ui/react-tabs":">=1.1.0","@radix-ui/react-label":">=2.1.0","@tanstack/react-query":">=5.0.0","@tanstack/react-table":">=8.0.0","@radix-ui/react-avatar":">=1.1.0","@radix-ui/react-dialog":">=1.1.0","@radix-ui/react-select":">=2.1.0","@radix-ui/react-switch":">=1.1.0","@radix-ui/react-popover":">=1.1.0","@radix-ui/react-tooltip":">=1.2.0","@radix-ui/react-checkbox":">=1.1.0","@radix-ui/react-progress":">=1.1.0","class-variance-authority":">=0.7.0","currency-code-symbol-map":">=3.0.0","@radix-ui/react-accordion":">=1.2.0","@radix-ui/react-separator":">=1.1.0","@radix-ui/react-collapsible":">=1.1.0","@radix-ui/react-radio-group":">=1.2.0","@radix-ui/react-dropdown-menu":">=2.1.0","@tanstack/react-query-devtools":">=5.0.0"},"peerDependenciesMeta":{"@tanstack/react-query-devtools":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ui-kit_0.1.1_1773935345659_0.394230228382461","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@adore96/ui-kit","version":"0.1.2","description":"Framework-agnostic UI kit: components, hooks, utilities, stores, DTOs, and validations extracted from neurocore-framework-fe.","author":{"name":"Neurocore Team"},"license":"MIT","repository":{"type":"git","url":""},"keywords":["neurocore","ui-kit","react","components","hooks","zustand","tanstack-query","radix-ui","zod","tailwind"],"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"},"./components":{"types":"./dist/components/index.d.ts","import":"./dist/components/index.js","require":"./dist/components/index.cjs"},"./hooks":{"types":"./dist/hooks/index.d.ts","import":"./dist/hooks/index.js","require":"./dist/hooks/index.cjs"},"./stores":{"types":"./dist/stores/index.d.ts","import":"./dist/stores/index.js","require":"./dist/stores/index.cjs"},"./utilities":{"types":"./dist/utilities/index.d.ts","import":"./dist/utilities/index.js","require":"./dist/utilities/index.cjs"},"./helpers":{"types":"./dist/helpers/index.d.ts","import":"./dist/helpers/index.js","require":"./dist/helpers/index.cjs"},"./dto":{"types":"./dist/dto/index.d.ts","import":"./dist/dto/index.js","require":"./dist/dto/index.cjs"},"./declarations":{"types":"./dist/declarations/index.d.ts","import":"./dist/declarations/index.js","require":"./dist/declarations/index.cjs"},"./validations":{"types":"./dist/validations/index.d.ts","import":"./dist/validations/index.js","require":"./dist/validations/index.cjs"},"./constants":{"types":"./dist/constants/index.d.ts","import":"./dist/constants/index.js","require":"./dist/constants/index.cjs"},"./services":{"types":"./dist/services/index.d.ts","import":"./dist/services/index.js","require":"./dist/services/index.cjs"},"./contexts":{"types":"./dist/contexts/index.d.ts","import":"./dist/contexts/index.js","require":"./dist/contexts/index.cjs"},"./lib":{"types":"./dist/lib/index.d.ts","import":"./dist/lib/index.js","require":"./dist/lib/index.cjs"}},"sideEffects":false,"scripts":{"build":"tsup","build:watch":"tsup --watch","typecheck":"tsc --noEmit","lint":"eslint src --ext .ts,.tsx","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","prepublishOnly":"pnpm run clean && pnpm run typecheck && pnpm run build","prepack":"pnpm run build","test:publish":"pnpm pack"},"peerDependencies":{"@hookform/resolvers":">=5.0.0","@radix-ui/react-accordion":">=1.2.0","@radix-ui/react-avatar":">=1.1.0","@radix-ui/react-checkbox":">=1.1.0","@radix-ui/react-collapsible":">=1.1.0","@radix-ui/react-dialog":">=1.1.0","@radix-ui/react-dropdown-menu":">=2.1.0","@radix-ui/react-label":">=2.1.0","@radix-ui/react-popover":">=1.1.0","@radix-ui/react-progress":">=1.1.0","@radix-ui/react-radio-group":">=1.2.0","@radix-ui/react-select":">=2.1.0","@radix-ui/react-separator":">=1.1.0","@radix-ui/react-slot":">=1.2.0","@radix-ui/react-switch":">=1.1.0","@radix-ui/react-tabs":">=1.1.0","@radix-ui/react-tooltip":">=1.2.0","@tanstack/react-query":">=5.0.0","@tanstack/react-query-devtools":">=5.0.0","@tanstack/react-table":">=8.0.0","axios":">=1.0.0","class-variance-authority":">=0.7.0","clsx":">=2.0.0","cmdk":">=1.0.0","date-fns":">=4.0.0","lucide-react":">=0.400.0","motion":">=10.0.0","react":">=19.0.0","react-day-picker":">=9.0.0","react-dom":">=19.0.0","react-hook-form":">=7.0.0","react-hot-toast":">=2.0.0","recharts":">=2.0.0","tailwind-merge":">=3.0.0","zod":">=3.0.0","zustand":">=4.0.0"},"peerDependenciesMeta":{"@tanstack/react-query-devtools":{"optional":true}},"devDependencies":{"@types/node":"^20.0.0","@types/react":"^19.0.0","@types/react-dom":"^19.0.0","tsup":"^8.4.0","typescript":"^5.8.3"},"packageManager":"pnpm@10.0.0","engines":{"node":">=18.0.0"},"publishConfig":{"access":"public"},"dependencies":{"pubnub":"^10.2.9"},"gitHead":"6b2113bc54db2e8b3f49a4db2a790bfb2356ba60","_id":"@adore96/ui-kit@0.1.2","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-odOs6KZHXGChDJEqdDP3IN4JpgY7BopG101e1pAPy3gMhYdhsH019QIrvJT8jTwqF9U4F6X7Naj8MbKSZ0EDfg==","shasum":"80384dc28fc38b09c2ee4b83afdaa8283eb6fd87","tarball":"https://registry.npmjs.org/@adore96/ui-kit/-/ui-kit-0.1.2.tgz","fileCount":99,"unpackedSize":6246022,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDVGsoA/XPNG2ahEhnzKNuJ8WqBDlZBiNEAIEmQUpIPEAIhAM4y9fa2q4C7eVmaO+rWdXjNcB9bISP9RoipQMBgwm4p"}]},"_npmUser":{"name":"adore96","email":"adorekasun@gmail.com"},"directories":{},"maintainers":[{"name":"adore96","email":"adorekasun@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ui-kit_0.1.2_1773936319051_0.09385593079558041"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-19T15:43:17.502Z","modified":"2026-03-19T16:05:19.352Z","0.1.0":"2026-03-19T15:43:17.819Z","0.1.1":"2026-03-19T15:49:05.891Z","0.1.2":"2026-03-19T16:05:19.225Z"},"author":{"name":"Neurocore Team"},"license":"MIT","keywords":["neurocore","ui-kit","react","components","hooks","zustand","tanstack-query","radix-ui","zod","tailwind"],"repository":{"type":"git","url":""},"description":"Framework-agnostic UI kit: components, hooks, utilities, stores, DTOs, and validations extracted from neurocore-framework-fe.","maintainers":[{"name":"adore96","email":"adorekasun@gmail.com"}],"readme":"# @adore96/neurocore-ui-kit\r\n\r\n> Framework-agnostic UI kit — components, hooks, stores, services, and utilities extracted from `neurocore-framework-fe`.\r\n\r\n[![npm version](https://img.shields.io/npm/v/@adore96/neurocore-ui-kit)](https://www.npmjs.com/package/@adore96/neurocore-ui-kit)\r\n[![TypeScript](https://img.shields.io/badge/TypeScript-5-blue)](https://www.typescriptlang.org/)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\r\n\r\n---\r\n\r\n## Contents\r\n\r\n- [Installation](#installation)\r\n- [Setup](#setup)\r\n  - [1. Wire your Axios instance](#1-wire-your-axios-instance)\r\n  - [2. Mount the providers](#2-mount-the-providers)\r\n  - [3. (Next.js only) next-auth wiring](#3-nextjs-only-next-auth-wiring)\r\n- [Sub-path imports](#sub-path-imports)\r\n- [Package modules](#package-modules)\r\n  - [Components](#components)\r\n  - [Hooks](#hooks)\r\n  - [Stores](#stores)\r\n  - [Services](#services)\r\n  - [Utilities](#utilities)\r\n  - [Helpers](#helpers)\r\n  - [Contexts](#contexts)\r\n  - [DTOs](#dtos)\r\n  - [Declarations](#declarations)\r\n  - [Validations](#validations)\r\n  - [Constants](#constants)\r\n- [Environment flags to parameterise](#environment-flags-to-parameterise)\r\n- [Peer dependencies](#peer-dependencies)\r\n- [Contributing](#contributing)\r\n- [Publishing](#publishing)\r\n- [License](#license)\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```bash\r\npnpm add @adore96/neurocore-ui-kit\r\n# or\r\nnpm install @adore96/neurocore-ui-kit\r\n# or\r\nyarn add @adore96/neurocore-ui-kit\r\n```\r\n\r\n---\r\n\r\n## Setup\r\n\r\n### 1. Wire your Axios instance\r\n\r\nThis package ships **no singleton Axios instance** — you create one and inject it. This lets the package work with any auth provider (next-auth, Clerk, Auth0, a custom JWT store, etc.).\r\n\r\n```ts\r\n// src/lib/http.ts  (your Next.js / Vite app)\r\nimport { createAxiosInstance } from \"@adore96/neurocore-ui-kit/utilities\";\r\nimport { getSession, signOut } from \"next-auth/react\"; // ← only in YOUR app\r\n\r\nexport const { axiosInstance, axiosPyInstance } = createAxiosInstance({\r\n  baseURL:       process.env.NEXT_PUBLIC_API_URL!,\r\n  pythonBaseURL: process.env.NEXT_PUBLIC_PYTHON_API_BASE_URL, // optional\r\n  timeout:       120_000, // optional, default 120 000 ms\r\n\r\n  // Return the bearer token for every authenticated request\r\n  getToken: async () => {\r\n    const session = await getSession();\r\n    return session?.accessToken ?? null;\r\n  },\r\n\r\n  // Called on HTTP 401 — redirect to login\r\n  onUnauthorized: () => signOut({ callbackUrl: \"/login\" }),\r\n\r\n  // Optional: forward API errors to your error UI\r\n  onApiError: ({ message, url, method, status }) => {\r\n    console.error(`[API] ${method?.toUpperCase()} ${url} → ${status}: ${message}`);\r\n  },\r\n});\r\n```\r\n\r\n### 2. Mount the providers\r\n\r\n```tsx\r\n// src/app/providers.tsx  (Next.js App Router example)\r\n\"use client\";\r\n\r\nimport {\r\n  QueryProvider,\r\n  ErrorProvider,\r\n  ModalProvider,\r\n  ServicesProvider,\r\n  createSearchService,\r\n  createEntityManagerService,\r\n  createUiLayoutService,\r\n  createUiFormService,\r\n  createUiFilterService,\r\n  createCommonService,\r\n} from \"@adore96/neurocore-ui-kit\";\r\nimport { axiosInstance } from \"@/lib/http\";\r\n\r\n// Build the services object once — stable reference, not recreated per render\r\nconst services = {\r\n  ...createSearchService(axiosInstance),\r\n  ...createEntityManagerService(axiosInstance),\r\n  ...createUiLayoutService(axiosInstance),\r\n  ...createUiFormService(axiosInstance),\r\n  ...createUiFilterService(axiosInstance),\r\n  ...createCommonService(axiosInstance),\r\n};\r\n\r\nexport function Providers({ children }: { children: React.ReactNode }) {\r\n  return (\r\n    <QueryProvider>\r\n      <ErrorProvider enabled={process.env.NEXT_PUBLIC_ENABLE_ERROR_DISPLAY === \"true\"}>\r\n        <ModalProvider>\r\n          <ServicesProvider services={services}>\r\n            {children}\r\n          </ServicesProvider>\r\n        </ModalProvider>\r\n      </ErrorProvider>\r\n    </QueryProvider>\r\n  );\r\n}\r\n```\r\n\r\n```tsx\r\n// src/app/layout.tsx\r\nimport { Providers } from \"./providers\";\r\n\r\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\r\n  return (\r\n    <html lang=\"en\">\r\n      <body>\r\n        <Providers>{children}</Providers>\r\n      </body>\r\n    </html>\r\n  );\r\n}\r\n```\r\n\r\n### 3. (Next.js only) next-auth wiring\r\n\r\n`next-auth` stays entirely in **your** application — this package has zero `next-auth` imports. The pattern above covers Next.js. For Vite or other frameworks:\r\n\r\n```ts\r\n// Vite + custom auth store\r\nimport { createAxiosInstance } from \"@adore96/neurocore-ui-kit/utilities\";\r\nimport { useAuthStore } from \"@adore96/neurocore-ui-kit/stores\";\r\n\r\nexport const { axiosInstance } = createAxiosInstance({\r\n  baseURL: import.meta.env.VITE_API_URL,\r\n  getToken: async () => useAuthStore.getState().user?.authToken ?? null,\r\n  onUnauthorized: () => {\r\n    useAuthStore.getState().logout();\r\n    window.location.href = \"/login\";\r\n  },\r\n});\r\n```\r\n\r\n---\r\n\r\n## Sub-path imports\r\n\r\nImport from the root barrel, or use sub-paths for leaner bundles:\r\n\r\n| Sub-path | Contents |\r\n|---|---|\r\n| (root) | Everything |\r\n| `/components` | All UI, shared, field, chart, table, and modal components |\r\n| `/hooks` | All React hooks |\r\n| `/stores` | Zustand stores |\r\n| `/services` | API service factories |\r\n| `/utilities` | Axios factory, event bus, utilities, QueryProvider, chat utils |\r\n| `/helpers` | Date, string, number, form, chart, address helpers |\r\n| `/contexts` | ErrorProvider, ModalProvider, ServicesProvider, SchemaVariantContext |\r\n| `/dto` | TypeScript DTO interfaces |\r\n| `/declarations` | Core type declarations |\r\n| `/validations` | Zod validation schemas |\r\n| `/constants` | Enums, query keys, API endpoints |\r\n\r\n---\r\n\r\n## Package modules\r\n\r\n### Components\r\n\r\n#### UI Primitives (`/components/ui`)\r\n\r\nShadcn + Radix UI components, ready to use with Tailwind CSS v4.\r\n\r\n```tsx\r\nimport { Button, Input, Badge, Card, Dialog } from \"@adore96/neurocore-ui-kit/components\";\r\n\r\n<Button variant=\"destructive\" size=\"sm\">Delete</Button>\r\n<Badge variant=\"outline\">Active</Badge>\r\n```\r\n\r\nFull list: `Accordion`, `Avatar`, `Badge`, `Button`, `Calendar`, `Card`, `Chart`, `Checkbox`, `Collapsible`, `Command`, `DatePicker`, `Dialog`, `DropdownMenu`, `DropdownWithSearch`, `Form`, `Input`, `Label`, `Pagination`, `Popover`, `Progress`, `RadioGroup`, `Select`, `SelectNative`, `Separator`, `Sheet`, `Sidebar`, `Skeleton`, `Switch`, `Table`, `Tabs`, `Textarea`, `TimePicker`, `Tooltip`.\r\n\r\n#### Shared Components (`/components/shared`)\r\n\r\n```tsx\r\nimport { DynamicBadge, Paginator, DynamicIcon } from \"@adore96/neurocore-ui-kit/components\";\r\n\r\n<DynamicBadge value=\"Approved\" color=\"#22c55e\" />\r\n<Paginator currentPage={1} totalPages={10} onPageChange={setPage} pageSize={20} onPageSizeChange={setSize} />\r\n<DynamicIcon name=\"user\" size={20} />\r\n```\r\n\r\n#### Field Components (`/components/fields`)\r\n\r\nDrop-in form fields that work with react-hook-form.\r\n\r\n```tsx\r\nimport { TextField, DropdownField, DatePickerField } from \"@adore96/neurocore-ui-kit/components\";\r\n\r\n<TextField\r\n  name=\"firstName\"\r\n  label=\"First name\"\r\n  placeholder=\"Jane\"\r\n  register={register}\r\n  error={errors.firstName?.message}\r\n/>\r\n```\r\n\r\n#### Chart Components (`/components/charts`)\r\n\r\nRecharts wrappers pre-configured with the Neurocore design tokens.\r\n\r\n```tsx\r\nimport { BarChart, LineChart, PieChart } from \"@adore96/neurocore-ui-kit/components\";\r\n\r\n<PieChart\r\n  data={[{ label: \"A\", value: 40 }, { label: \"B\", value: 60 }]}\r\n  height={300}\r\n/>\r\n```\r\n\r\n#### Modal Components (`/components/modals`)\r\n\r\n```tsx\r\nimport { SecondConfirmationModal } from \"@adore96/neurocore-ui-kit/components\";\r\n\r\n<SecondConfirmationModal\r\n  isOpen={open}\r\n  onConfirm={handleDelete}\r\n  onCancel={() => setOpen(false)}\r\n  message=\"Are you sure you want to delete this record?\"\r\n/>\r\n```\r\n\r\n---\r\n\r\n### Hooks\r\n\r\n```ts\r\nimport {\r\n  useDebounce,\r\n  useMobile,\r\n  useLocalStorageCache,\r\n  useKeyboardKeys,\r\n  useScrollHandler,\r\n  useReadMore,\r\n  usePerformanceMetrics,\r\n  useDropdownState,\r\n  useFormState,\r\n  useFormSubmit,\r\n  useFormStateWithInitialData,\r\n  useFormOptionsFromCache,\r\n  useFetchSelectOptionsFromEndpoint,\r\n  useChartData,\r\n} from \"@adore96/neurocore-ui-kit/hooks\";\r\n```\r\n\r\n#### `useDebounce`\r\n\r\n```ts\r\nconst debouncedQuery = useDebounce(searchQuery, 300);\r\n```\r\n\r\n#### `useMobile`\r\n\r\n```ts\r\nconst isMobile = useMobile(); // true when viewport < 768 px\r\n```\r\n\r\n#### `useFetchFormSchema` — injectable fetch function\r\n\r\n```tsx\r\nimport { useFetchFormSchema } from \"@adore96/neurocore-ui-kit/hooks\";\r\nimport { createUiFormService } from \"@adore96/neurocore-ui-kit/services\";\r\nimport { axiosInstance } from \"@/lib/http\";\r\n\r\nconst { getFormSchemaByEntity } = createUiFormService(axiosInstance);\r\n\r\nconst { formSchema, isLoading } = useFetchFormSchema(\"customer\", {\r\n  fetchFn: getFormSchemaByEntity,\r\n});\r\n```\r\n\r\n#### `useFetchLayoutSchema` — injectable fetch function\r\n\r\n```tsx\r\nimport { useFetchLayoutSchema } from \"@adore96/neurocore-ui-kit/hooks\";\r\nimport { createUiLayoutService } from \"@adore96/neurocore-ui-kit/services\";\r\nimport { axiosInstance } from \"@/lib/http\";\r\n\r\nconst { getPageLayout } = createUiLayoutService(axiosInstance);\r\n\r\nconst { layout, isLoading } = useFetchLayoutSchema(\"customer\", {\r\n  fetchFn: getPageLayout,\r\n});\r\n```\r\n\r\n#### `useTable`\r\n\r\nRequires `<ServicesProvider>` in the tree (see [Setup](#setup)).\r\n\r\n```tsx\r\nconst { table, isLoading, totalCount } = useTable({\r\n  entityName: \"customer\",\r\n  visibleColumns: [\r\n    { key: \"customerName\", label: \"Name\", sortable: true },\r\n    { key: \"email\", label: \"Email\" },\r\n  ],\r\n  pagination: { pageSize: 20, sortField: \"createdDate\", sortDirection: \"desc\" },\r\n});\r\n```\r\n\r\n#### `useChartData`\r\n\r\nRequires `<ServicesProvider>` in the tree.\r\n\r\n```tsx\r\nconst { chartData, isLoading } = useChartData({\r\n  searchEntity: \"view_sales_by_region\",\r\n  labelKey: \"region\",\r\n  valueKey: \"totalRevenue\",\r\n  limit: 10,\r\n});\r\n```\r\n\r\n---\r\n\r\n### Stores\r\n\r\n#### `useAuthStore`\r\n\r\n```ts\r\nimport { useAuthStore } from \"@adore96/neurocore-ui-kit/stores\";\r\n\r\nconst { user, login, logout, isLoggedIn } = useAuthStore();\r\n```\r\n\r\n#### Custom storage key (multi-tenant / micro-frontends)\r\n\r\n```ts\r\nimport { createAuthStore } from \"@adore96/neurocore-ui-kit/stores\";\r\n\r\n// Each micro-frontend gets its own isolated store\r\nexport const useAuthStore = createAuthStore(\"my-app-v2-auth\");\r\n```\r\n\r\n#### `useFilterStore`\r\n\r\n```ts\r\nimport { useFilterStore } from \"@adore96/neurocore-ui-kit/stores\";\r\n\r\nconst { setFilter, clearFilters, getEntityFilters, setCurrentPage, getCurrentPage } =\r\n  useFilterStore();\r\n\r\n// Set a filter for a specific entity\r\nsetFilter(\"customer\", \"status\", \"active\");\r\n\r\n// Read all filters for an entity\r\nconst filters = getEntityFilters(\"customer\");\r\n```\r\n\r\n#### `useFormStore`\r\n\r\n```ts\r\nimport { useFormStore } from \"@adore96/neurocore-ui-kit/stores\";\r\n\r\nconst { formStoreData, setFormStoreData } = useFormStore();\r\n```\r\n\r\n---\r\n\r\n### Services\r\n\r\nAll services are **factory functions** that accept a configured Axios instance.\r\n\r\n```ts\r\nimport {\r\n  createSearchService,\r\n  createEntityManagerService,\r\n  createUiLayoutService,\r\n  createUiFormService,\r\n  createUiFilterService,\r\n  createCommonService,\r\n  createReportService,\r\n} from \"@adore96/neurocore-ui-kit/services\";\r\nimport { axiosInstance } from \"@/lib/http\";\r\n\r\nconst search  = createSearchService(axiosInstance);\r\nconst entity  = createEntityManagerService(axiosInstance);\r\nconst layout  = createUiLayoutService(axiosInstance);\r\nconst form    = createUiFormService(axiosInstance);\r\nconst filter  = createUiFilterService(axiosInstance);\r\nconst common  = createCommonService(axiosInstance);\r\nconst reports = createReportService(axiosInstance);\r\n\r\n// Usage\r\nconst results = await search.getTableDataBySearchQuery(\"customer\", query);\r\nconst schema  = await form.getFormSchemaByEntity(\"customer\");\r\nconst page    = await layout.getPageLayout(\"customer\");\r\nawait entity.postEntityData(\"/entities/customer\", payload);\r\nawait entity.deleteEntityData(\"/entities\", \"customer\", id);\r\nconst types   = await common.getSampleTypes();\r\nconst report  = await reports.requestReportDownload(\"chargeable-item-trend\", {\r\n  startMonth: \"2024-01\",\r\n  endMonth:   \"2024-12\",\r\n});\r\n```\r\n\r\n---\r\n\r\n### Utilities\r\n\r\n#### `createAxiosInstance`\r\n\r\nSee [Setup → Wire your Axios instance](#1-wire-your-axios-instance).\r\n\r\n#### `EventBus`\r\n\r\nPublish/subscribe bus for cross-component communication without prop drilling.\r\n\r\n```ts\r\nimport { events } from \"@adore96/neurocore-ui-kit/utilities\";\r\n\r\n// Subscribe\r\nconst unsubscribe = events.register(\"file-uploaded\", async (payload) => {\r\n  await refetch();\r\n});\r\n\r\n// Publish\r\nawait events.trigger(\"file-uploaded\", { fileId: \"abc\" });\r\n\r\n// Cleanup\r\nunsubscribe();\r\n```\r\n\r\n#### `conditionalRenderer`\r\n\r\n```ts\r\nimport {\r\n  shouldRenderComponent,\r\n  evaluateSimpleCondition,\r\n} from \"@adore96/neurocore-ui-kit/utilities\";\r\n\r\nconst show = shouldRenderComponent(\r\n  { condition: \"status === 'active'\" },\r\n  { status: \"active\" }\r\n); // true\r\n\r\nconst result = evaluateSimpleCondition(\"count > 5\", { count: 10 }); // true\r\n```\r\n\r\n#### `getNestedData`\r\n\r\n```ts\r\nimport { getNestedData } from \"@adore96/neurocore-ui-kit/utilities\";\r\n\r\nconst data = { user: { address: { city: \"Sydney\" } } };\r\ngetNestedData(data, \"user.address.city\"); // \"Sydney\"\r\ngetNestedData(data, \"user.phones[0].number\", \"N/A\"); // \"N/A\"\r\n```\r\n\r\n#### `zodErrorUtils`\r\n\r\n```ts\r\nimport {\r\n  validateWithZod,\r\n  zodErrorsToFormErrors,\r\n} from \"@adore96/neurocore-ui-kit/utilities\";\r\nimport { z } from \"zod\";\r\n\r\nconst schema = z.object({ name: z.string().min(1) });\r\nconst result = validateWithZod(schema, { name: \"\" });\r\n\r\nif (!result.success) {\r\n  console.log(result.errors); // { name: \"String must contain at least 1 character(s)\" }\r\n}\r\n```\r\n\r\n#### `QueryProvider`\r\n\r\n```tsx\r\nimport { QueryProvider } from \"@adore96/neurocore-ui-kit/utilities\";\r\n\r\n<QueryProvider>\r\n  <App />\r\n</QueryProvider>\r\n```\r\n\r\n---\r\n\r\n### Helpers\r\n\r\n```ts\r\nimport {\r\n  formatIsoToReadable,   // \"15 Jan 2025, 9:12 AM\"\r\n  getDefaultDateRange,   // { fromDate, toDate } ← last 7 days\r\n  formatNumberWithCommas,// 354535.48 → \"354,535.48\"\r\n  capitalizeFirstLetter,\r\n  toTitleCase,\r\n  truncateString,\r\n  toKebabCase,\r\n  toCamelCase,\r\n  snakeToTitle,\r\n  parseErrorMessage,     // Extracts human-readable message from AxiosError\r\n  removeEmptyStrings,    // Deep-removes \"\" from objects/arrays\r\n  removeNullValues,      // Deep-removes null from objects/arrays\r\n  searchQueryBuilder,    // Builds NL search query strings\r\n  getAddressString,      // Formats Address object → \"12 Main St, Sydney, NSW 2000\"\r\n} from \"@adore96/neurocore-ui-kit/helpers\";\r\n```\r\n\r\n---\r\n\r\n### Contexts\r\n\r\n#### `ErrorProvider` / `useError`\r\n\r\n```tsx\r\nimport { ErrorProvider, useError } from \"@adore96/neurocore-ui-kit/contexts\";\r\n\r\n// In layout\r\n<ErrorProvider enabled={process.env.NEXT_PUBLIC_ENABLE_ERROR_DISPLAY === \"true\"}>\r\n  <App />\r\n</ErrorProvider>\r\n\r\n// In any component\r\nconst { errors, clearAllErrors } = useError();\r\n```\r\n\r\n#### `ModalProvider` / `useModal`\r\n\r\n```tsx\r\nimport { ModalProvider, useModal } from \"@adore96/neurocore-ui-kit/contexts\";\r\n\r\n// Open a modal\r\nconst { openModal, closeModal } = useModal();\r\nopenModal(\"customer\", customerId, \"edit\");\r\n```\r\n\r\n#### `ServicesProvider` / `useServices`\r\n\r\n```tsx\r\nimport { ServicesProvider, useServices } from \"@adore96/neurocore-ui-kit/contexts\";\r\n\r\n// In a component\r\nconst { getTableDataBySearchQuery } = useServices();\r\nconst results = await getTableDataBySearchQuery(\"customer\", query);\r\n```\r\n\r\n---\r\n\r\n### DTOs\r\n\r\n```ts\r\nimport {\r\n  CommonAPIResponse,\r\n  DataTableResponseDto,\r\n  LoginRequestDto,\r\n  UserDto,\r\n} from \"@adore96/neurocore-ui-kit/dto\";\r\n\r\nconst response: DataTableResponseDto<UserDto> = await fetchUsers();\r\nresponse.results.forEach((u: UserDto) => console.log(u.email));\r\n```\r\n\r\n---\r\n\r\n### Declarations\r\n\r\n```ts\r\nimport {\r\n  FormDeclaration,\r\n  PageDeclaration,\r\n  FilterSchema,\r\n  EntityData,\r\n  FieldSchema,\r\n  PageComponent,\r\n  ConditionalRender,\r\n  ButtonClickAction,\r\n} from \"@adore96/neurocore-ui-kit/declarations\";\r\n```\r\n\r\n---\r\n\r\n### Validations\r\n\r\n```ts\r\nimport {\r\n  adornmentFormSchema,\r\n  analyteFormSchema,\r\n  supportingValueFormSchema,\r\n  testMethodFormSchema,\r\n  SUPPORTED_COMPONENT_TYPES,\r\n  DYNAMIC_COMPONENT_TYPE,\r\n} from \"@adore96/neurocore-ui-kit/validations\";\r\n\r\nconst result = analyteFormSchema.safeParse(formData);\r\nif (!result.success) {\r\n  console.log(result.error.flatten());\r\n}\r\n```\r\n\r\n---\r\n\r\n### Constants\r\n\r\n```ts\r\nimport {\r\n  FIELD_TYPE_ENUM,\r\n  PAGE_COMPONENT_TYPE_ENUM,\r\n  BUTTON_ACTION_TYPE_ENUM,\r\n  SORT_DIRECTION_ENUM,\r\n  ENTITY_STATUS_ENUM,\r\n  FORM_SUBMIT_TYPES_ENUM,\r\n  LAYOUT_TYPE_ENUM,\r\n  FILE_MIME_TYPE_ENUM,\r\n  QUERY_CATEGORY,\r\n  QUERY_STALE_TIME,\r\n  ENTITY_MANAGER_ENDPOINTS,\r\n  SEARCH_CONTROLLER_ENDPOINTS,\r\n  AUTH_SERVICE_ENDPOINTS,\r\n} from \"@adore96/neurocore-ui-kit/constants\";\r\n```\r\n\r\n---\r\n\r\n## Environment flags to parameterise\r\n\r\nBefore publishing, replace the following in **your** application (not in this package):\r\n\r\n| Original env var | Package equivalent | Where |\r\n|---|---|---|\r\n| `NEXT_PUBLIC_API_URL` | `createAxiosInstance({ baseURL })` | `src/lib/http.ts` |\r\n| `NEXT_PUBLIC_PYTHON_API_BASE_URL` | `createAxiosInstance({ pythonBaseURL })` | `src/lib/http.ts` |\r\n| `NEXT_PUBLIC_ENABLE_GLOBAL_ERROR_DISPLAY` | `<ErrorProvider enabled={...}>` | `src/app/providers.tsx` |\r\n| `NEXT_PUBLIC_RUN_LOCAL` | Pass `fetchFn: getLocalFormJson` vs `getFormSchemaByEntity` | Hook call sites |\r\n| `neurocore-auth` localStorage key | `createAuthStore(\"my-app-key\")` | Auth store init |\r\n\r\n---\r\n\r\n## Peer dependencies\r\n\r\nThis package does **not** bundle React, Tailwind, or any Radix/Tanstack library. Install them in your application:\r\n\r\n```bash\r\npnpm add react react-dom \\\r\n  @tanstack/react-query @tanstack/react-table \\\r\n  zustand axios zod \\\r\n  lucide-react recharts date-fns \\\r\n  tailwind-merge clsx class-variance-authority \\\r\n  react-hook-form @hookform/resolvers \\\r\n  react-hot-toast react-day-picker cmdk \\\r\n  @radix-ui/react-accordion @radix-ui/react-avatar \\\r\n  @radix-ui/react-checkbox @radix-ui/react-collapsible \\\r\n  @radix-ui/react-dialog @radix-ui/react-dropdown-menu \\\r\n  @radix-ui/react-label @radix-ui/react-popover \\\r\n  @radix-ui/react-progress @radix-ui/react-radio-group \\\r\n  @radix-ui/react-select @radix-ui/react-separator \\\r\n  @radix-ui/react-slot @radix-ui/react-switch \\\r\n  @radix-ui/react-tabs @radix-ui/react-tooltip\r\n```\r\n\r\n---\r\n\r\n## Contributing\r\n\r\n1. Clone the repository from Bitbucket.\r\n2. `pnpm install`\r\n3. `pnpm run build:watch` — incremental builds during development.\r\n4. `pnpm run typecheck` — run before every commit.\r\n5. Update `CHANGELOG.md` under `[Unreleased]` when adding features.\r\n\r\n---\r\n\r\n## Publishing\r\n\r\nReleases are automated via Bitbucket Pipelines. To publish a new version:\r\n\r\n```bash\r\n# 1. Update version in package.json\r\npnpm version patch   # or minor / major\r\n\r\n# 2. Push the tag — the pipeline handles the rest\r\ngit push && git push --tags\r\n```\r\n\r\nThe pipeline (`bitbucket-pipelines.yml`) will:\r\n1. Verify the git tag matches `package.json` version.\r\n2. Run `pnpm run typecheck` and `pnpm run build`.\r\n3. Publish to NPM with `--access public`.\r\n\r\nRequires the `NPM_TOKEN` repository variable to be set in Bitbucket\r\n(**Repository settings → Repository variables**).\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT © Adore96\r\n","readmeFilename":"README.md"}