{"_id":"@divami-labs/experiential-ui","_rev":"6-86ebf1cc67a0c44a3b1c19d6dc241a33","name":"@divami-labs/experiential-ui","dist-tags":{"latest":"1.0.5"},"versions":{"1.0.0":{"name":"@divami-labs/experiential-ui","version":"1.0.0","keywords":["react","dashboard","ai","chart","plotly","data-visualization","dynamic-ui","theming","component-library"],"license":"MIT","_id":"@divami-labs/experiential-ui@1.0.0","maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"homepage":"https://github.com/divamidesignlabs/Simulator_POC#readme","bugs":{"url":"https://github.com/divamidesignlabs/Simulator_POC/issues"},"dist":{"shasum":"978c9c6eaa97aabf0234824f2eb9bbe7ef4580f5","tarball":"https://registry.npmjs.org/@divami-labs/experiential-ui/-/experiential-ui-1.0.0.tgz","fileCount":34,"integrity":"sha512-uJQWzO7S8R/avRIF98hihL7jdHJm3a1+Ag05WPydc7AhtDFOpWfdGZB6WYhPq32sqfWZOTHQSymO8BpOxveczQ==","signatures":[{"sig":"MEYCIQCzbUN/lAXXdkAu2mXnx0+KsAAzRepc7CX3tbjplp0EWgIhAOHDBkZUHXU2KAcBiJAF5ovEZcmox6RCtIzTG6BKdAFC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131659},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles":"./dist/experiential-ui.css"},"gitHead":"13ca6bebc2ea2783b74040af2359f5ceadde394b","scripts":{"dev":"vite","lint":"eslint .","build":"tsc -b && vite build","preview":"vite preview","build:lib":"vite build --config vite.lib.config.ts","prepublishOnly":"npm run build:lib"},"_npmUser":{"name":"divami-artefacts","email":"devops@divami.com"},"repository":{"url":"git+https://github.com/divamidesignlabs/Simulator_POC.git","type":"git"},"_npmVersion":"10.9.4","description":"AI-powered dynamic dashboard renderer for React — renders DashboardSpec JSON into fully interactive charts, tables, cards and lists with cross-widget selection, drilldowns and theming.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.22.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","axios":"^1.13.6","react":"^19.2.0","eslint":"^9.39.1","globals":"^16.5.0","react-dom":"^19.2.0","@eslint/js":"^9.39.1","typescript":"~5.9.3","@types/node":"^24.10.1","@types/react":"^19.2.7","vite-plugin-dts":"^4.5.4","@types/plotly.js":"^2.35.4","@types/react-dom":"^19.2.3","typescript-eslint":"^8.48.0","@vitejs/plugin-react":"^5.1.1","@types/react-plotly.js":"^2.6.4","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.24"},"peerDependencies":{"axios":">=1.0.0","react":">=18.0.0","plotly.js":">=2.0.0","react-dom":">=18.0.0","react-plotly.js":">=2.0.0"},"peerDependenciesMeta":{"axios":{"optional":false},"plotly.js":{"optional":false},"react-plotly.js":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/experiential-ui_1.0.0_1774522382527_0.663507205052466","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@divami-labs/experiential-ui","version":"1.0.1","keywords":["react","dashboard","ai","chart","plotly","data-visualization","dynamic-ui","theming","component-library"],"license":"MIT","_id":"@divami-labs/experiential-ui@1.0.1","maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"homepage":"https://github.com/divamidesignlabs/Simulator_POC#readme","bugs":{"url":"https://github.com/divamidesignlabs/Simulator_POC/issues"},"dist":{"shasum":"84bcbf4a579b2df9337957fc16fab374c751dd08","tarball":"https://registry.npmjs.org/@divami-labs/experiential-ui/-/experiential-ui-1.0.1.tgz","fileCount":34,"integrity":"sha512-XxLzTy/pHay3e9DIGdff8aw5PM+egHTtmPfDdOHVLB5CkNNObliS0Cg836R4XupATBNuD7hFG7Zox6Yq85E4iA==","signatures":[{"sig":"MEUCIAgQoIiZA5yG2ipgGh24Iq7gVpQjpA4L9LCweWGjrxwyAiEA9xzHtZP780/xmD40JykVBX+im2u9A8CU7NXM8sbQDHA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131540},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles":"./dist/experiential-ui.css"},"gitHead":"b44dece4a082e10b8bfd4d04a347782bc766a6cf","scripts":{"dev":"vite","lint":"eslint .","build":"tsc -b && vite build","preview":"vite preview","build:lib":"vite build --config vite.lib.config.ts","prepublishOnly":"npm run build:lib"},"_npmUser":{"name":"divami-artefacts","email":"devops@divami.com"},"repository":{"url":"git+https://github.com/divamidesignlabs/Simulator_POC.git","type":"git"},"_npmVersion":"10.9.4","description":"AI-powered dynamic dashboard renderer for React — renders DashboardSpec JSON into fully interactive charts, tables, cards and lists with cross-widget selection, drilldowns and theming.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.22.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","axios":"^1.13.6","react":"^19.2.0","eslint":"^9.39.1","globals":"^16.5.0","react-dom":"^19.2.0","@eslint/js":"^9.39.1","typescript":"~5.9.3","@types/node":"^24.10.1","@types/react":"^19.2.7","vite-plugin-dts":"^4.5.4","@types/plotly.js":"^2.35.4","@types/react-dom":"^19.2.3","typescript-eslint":"^8.48.0","@vitejs/plugin-react":"^5.1.1","@types/react-plotly.js":"^2.6.4","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.24"},"peerDependencies":{"axios":">=1.0.0","react":">=18.0.0","plotly.js":">=2.0.0","react-dom":">=18.0.0","react-plotly.js":">=2.0.0"},"peerDependenciesMeta":{"axios":{"optional":false},"plotly.js":{"optional":false},"react-plotly.js":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/experiential-ui_1.0.1_1774525583183_0.18454335961288781","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@divami-labs/experiential-ui","version":"1.0.2","keywords":["react","dashboard","ai","chart","plotly","data-visualization","dynamic-ui","theming","component-library"],"license":"MIT","_id":"@divami-labs/experiential-ui@1.0.2","maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"homepage":"https://github.com/divamidesignlabs/Simulator_POC#readme","bugs":{"url":"https://github.com/divamidesignlabs/Simulator_POC/issues"},"dist":{"shasum":"88781e702f1b066d50cc5e733c581de6af8c6d74","tarball":"https://registry.npmjs.org/@divami-labs/experiential-ui/-/experiential-ui-1.0.2.tgz","fileCount":35,"integrity":"sha512-xFyTXBjn/bbTkixzqQ42IE16H46dWC054HRV6HMlsAhZWecBbIOk2ZSx9H+fH5wnjMVTw0CHRZ92jjaION+dLw==","signatures":[{"sig":"MEYCIQCXrTUiXoIsl8VXs4T/uqgJq1rJxF6Ta6wA9s4Pu5C+vAIhANSVfSyFzHbbrlI3rjwtNZzJU4hHpTWaNGw13V0bRUwT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":141528},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles":"./dist/experiential-ui.css"},"gitHead":"146763960ff243c3e87898afe827242a608a739d","scripts":{"dev":"vite","lint":"eslint .","build":"tsc -b && vite build","preview":"vite preview","build:lib":"vite build --config vite.lib.config.ts","prepublishOnly":"npm run build:lib"},"_npmUser":{"name":"divami-artefacts","email":"devops@divami.com"},"repository":{"url":"git+https://github.com/divamidesignlabs/Simulator_POC.git","type":"git"},"_npmVersion":"10.9.4","description":"AI-powered dynamic dashboard renderer for React — renders DashboardSpec JSON into fully interactive charts, tables, cards and lists with cross-widget selection, drilldowns and theming.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.22.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","axios":"^1.13.6","react":"^19.2.0","eslint":"^9.39.1","globals":"^16.5.0","react-dom":"^19.2.0","@eslint/js":"^9.39.1","typescript":"~5.9.3","@types/node":"^24.10.1","@types/react":"^19.2.7","vite-plugin-dts":"^4.5.4","@types/plotly.js":"^2.35.4","@types/react-dom":"^19.2.3","typescript-eslint":"^8.48.0","@vitejs/plugin-react":"^5.1.1","@types/react-plotly.js":"^2.6.4","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.24"},"peerDependencies":{"axios":">=1.0.0","react":">=18.0.0","plotly.js":">=2.0.0","react-dom":">=18.0.0","react-plotly.js":">=2.0.0"},"peerDependenciesMeta":{"axios":{"optional":false},"plotly.js":{"optional":false},"react-plotly.js":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/experiential-ui_1.0.2_1774855274577_0.8206837182000137","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@divami-labs/experiential-ui","version":"1.0.3","keywords":["react","dashboard","ai","chart","plotly","data-visualization","dynamic-ui","theming","component-library"],"license":"MIT","_id":"@divami-labs/experiential-ui@1.0.3","maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"homepage":"https://github.com/divamidesignlabs/Simulator_POC#readme","bugs":{"url":"https://github.com/divamidesignlabs/Simulator_POC/issues"},"dist":{"shasum":"306428ba10af3e35909bbc1ceb04101b100951f3","tarball":"https://registry.npmjs.org/@divami-labs/experiential-ui/-/experiential-ui-1.0.3.tgz","fileCount":35,"integrity":"sha512-GIfN2tinqTQkGhnpkeSLKzIn8sxMRXQ/+FH8zZ6LpL+ZeI0HkvvStoJmTIEjBqdMGaAkKXp2OXpu+QD6B+xdYQ==","signatures":[{"sig":"MEYCIQC1l4FYxYPEDycX/gv93/3IjsV7FT5D6e8k0HAfFBM6AAIhAKNbPqG8yuySHYyoYzBImunb6IeaZxz84j4o55xAIhZw","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":141648},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles":"./dist/experiential-ui.css"},"gitHead":"e849372a96d9c0d4a47d9f799e7073ce3ca571a3","scripts":{"dev":"vite","lint":"eslint .","build":"tsc -b && vite build","preview":"vite preview","build:lib":"vite build --config vite.lib.config.ts","prepublishOnly":"npm run build:lib"},"_npmUser":{"name":"divami-artefacts","email":"devops@divami.com"},"repository":{"url":"git+https://github.com/divamidesignlabs/Simulator_POC.git","type":"git"},"_npmVersion":"10.9.7","description":"AI-powered dynamic dashboard renderer for React — renders DashboardSpec JSON into fully interactive charts, tables, cards and lists with cross-widget selection, drilldowns and theming.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.22.2","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","axios":"^1.13.6","react":"^19.2.0","eslint":"^9.39.1","globals":"^16.5.0","react-dom":"^19.2.0","@eslint/js":"^9.39.1","typescript":"~5.9.3","@types/node":"^24.10.1","@types/react":"^19.2.7","vite-plugin-dts":"^4.5.4","@types/plotly.js":"^2.35.4","@types/react-dom":"^19.2.3","typescript-eslint":"^8.48.0","@vitejs/plugin-react":"^5.1.1","@types/react-plotly.js":"^2.6.4","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.24"},"peerDependencies":{"axios":">=1.0.0","react":">=18.0.0","plotly.js":">=2.0.0","react-dom":">=18.0.0","react-plotly.js":">=2.0.0"},"peerDependenciesMeta":{"axios":{"optional":false},"plotly.js":{"optional":false},"react-plotly.js":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/experiential-ui_1.0.3_1775135063941_0.650348641002823","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@divami-labs/experiential-ui","version":"1.0.4","keywords":["react","dashboard","ai","chart","plotly","data-visualization","dynamic-ui","theming","component-library"],"license":"MIT","_id":"@divami-labs/experiential-ui@1.0.4","maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"homepage":"https://github.com/divamidesignlabs/ai-experiential-ui-and-agent#readme","bugs":{"url":"https://github.com/divamidesignlabs/ai-experiential-ui-and-agent/issues"},"dist":{"shasum":"024aaf973a81176c6744b13126b88ba78299632e","tarball":"https://registry.npmjs.org/@divami-labs/experiential-ui/-/experiential-ui-1.0.4.tgz","fileCount":35,"integrity":"sha512-L7axo6SwY0rIUUj94f65YKGQBfq92giObp+QGBo2irWaraeys21EjNOtZqEZKVMuTzL4CYwMgsO1P+qUUNZNZw==","signatures":[{"sig":"MEQCICKUHdRgmC3K27X1TJjleNRm+AWOI5gBUT6wUlUxTOwQAiBSAlSNrVs7jfaIJ0DIF2SZHuxHIZmp2c+uPapoYPCobg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":141693},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles":"./dist/experiential-ui.css"},"gitHead":"58430763055cc1143503f8606f21605ec9dbb908","scripts":{"dev":"vite","lint":"eslint .","build":"tsc -b && vite build","preview":"vite preview","build:lib":"vite build --config vite.lib.config.ts","prepublishOnly":"npm run build:lib"},"_npmUser":{"name":"divami-artefacts","email":"devops@divami.com"},"repository":{"url":"git+https://github.com/divamidesignlabs/ai-experiential-ui-and-agent.git","type":"git"},"_npmVersion":"10.9.7","description":"AI-powered dynamic dashboard renderer for React — renders DashboardSpec JSON into fully interactive charts, tables, cards and lists with cross-widget selection, drilldowns and theming.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"22.22.2","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","axios":"^1.13.6","react":"^19.2.0","eslint":"^9.39.1","globals":"^16.5.0","react-dom":"^19.2.0","@eslint/js":"^9.39.1","typescript":"~5.9.3","@types/node":"^24.10.1","@types/react":"^19.2.7","vite-plugin-dts":"^4.5.4","@types/plotly.js":"^2.35.4","@types/react-dom":"^19.2.3","typescript-eslint":"^8.48.0","@vitejs/plugin-react":"^5.1.1","@types/react-plotly.js":"^2.6.4","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.24"},"peerDependencies":{"axios":">=1.0.0","react":">=18.0.0","plotly.js":">=2.0.0","react-dom":">=18.0.0","react-plotly.js":">=2.0.0"},"peerDependenciesMeta":{"axios":{"optional":false},"plotly.js":{"optional":false},"react-plotly.js":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/experiential-ui_1.0.4_1775211433123_0.685313222721947","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@divami-labs/experiential-ui","version":"1.0.5","description":"AI-powered dynamic dashboard renderer for React — renders DashboardSpec JSON into fully interactive charts, tables, cards and lists with cross-widget selection, drilldowns and theming.","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"},"./styles":"./dist/experiential-ui.css"},"sideEffects":["*.css"],"keywords":["react","dashboard","ai","chart","plotly","data-visualization","dynamic-ui","theming","component-library"],"homepage":"https://github.com/divamidesignlabs/ai-experiential-ui-and-agent#readme","repository":{"type":"git","url":"git+https://github.com/divamidesignlabs/ai-experiential-ui-and-agent.git"},"bugs":{"url":"https://github.com/divamidesignlabs/ai-experiential-ui-and-agent/issues"},"license":"MIT","scripts":{"dev":"vite","build":"tsc -b && vite build","build:lib":"vite build --config vite.lib.config.ts","prepublishOnly":"npm run build:lib","lint":"eslint .","preview":"vite preview"},"peerDependencies":{"axios":">=1.0.0","plotly.js":">=2.0.0","react":">=18.0.0","react-dom":">=18.0.0","react-plotly.js":">=2.0.0"},"peerDependenciesMeta":{"axios":{"optional":false},"plotly.js":{"optional":false},"react-plotly.js":{"optional":false}},"dependencies":{},"devDependencies":{"axios":"^1.13.6","@eslint/js":"^9.39.1","@types/node":"^24.10.1","@types/plotly.js":"^2.35.4","@types/react":"^19.2.7","@types/react-dom":"^19.2.3","@types/react-plotly.js":"^2.6.4","@vitejs/plugin-react":"^5.1.1","eslint":"^9.39.1","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.24","globals":"^16.5.0","react":"^19.2.0","react-dom":"^19.2.0","typescript":"~5.9.3","typescript-eslint":"^8.48.0","vite":"^7.3.1","vite-plugin-dts":"^4.5.4"},"_id":"@divami-labs/experiential-ui@1.0.5","gitHead":"158bde3a06cdff9eb7c2afb40101f6597dfa2ffe","_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-NtSVRifTn7/tscPkLDk2BvzhdeyntBmbcXcombM18SQm+98u9ty2SU8EfF9ceLZCO/HY4mBvjERu2cuwlFEQYA==","shasum":"30700f13c5ff56831fd7f33b3c40d722ec92876b","tarball":"https://registry.npmjs.org/@divami-labs/experiential-ui/-/experiential-ui-1.0.5.tgz","fileCount":35,"unpackedSize":141716,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHA1JxW6CTxlWhhXbU15T15YlZdDsGCBHFRTSdULRMRvAiEA4kp8lMMrk2GwEYSlndKAk6JbAt12vEsytZ71BgMfhXU="}]},"_npmUser":{"name":"divami-artefacts","email":"devops@divami.com"},"directories":{},"maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/experiential-ui_1.0.5_1775212243951_0.7870758198136247"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T10:53:02.408Z","modified":"2026-04-03T10:30:44.251Z","1.0.0":"2026-03-26T10:53:02.649Z","1.0.1":"2026-03-26T11:46:23.339Z","1.0.2":"2026-03-30T07:21:14.747Z","1.0.3":"2026-04-02T13:04:24.085Z","1.0.4":"2026-04-03T10:17:13.265Z","1.0.5":"2026-04-03T10:30:44.104Z"},"bugs":{"url":"https://github.com/divamidesignlabs/ai-experiential-ui-and-agent/issues"},"license":"MIT","homepage":"https://github.com/divamidesignlabs/ai-experiential-ui-and-agent#readme","keywords":["react","dashboard","ai","chart","plotly","data-visualization","dynamic-ui","theming","component-library"],"repository":{"type":"git","url":"git+https://github.com/divamidesignlabs/ai-experiential-ui-and-agent.git"},"description":"AI-powered dynamic dashboard renderer for React — renders DashboardSpec JSON into fully interactive charts, tables, cards and lists with cross-widget selection, drilldowns and theming.","maintainers":[{"name":"divami-artefacts","email":"devops@divami.com"}],"readme":"# @divami-labs/experiential-ui\n\nA React component library that turns a JSON spec into a fully interactive dashboard — charts, tables, cards, and lists — with cross-widget selection, drilldown navigation, and theming built in.\n\n[![npm version](https://img.shields.io/npm/v/@divami-labs/experiential-ui)](https://www.npmjs.com/package/@divami-labs/experiential-ui)\n[![license](https://img.shields.io/npm/l/@divami-labs/experiential-ui)](./LICENSE)\n\n---\n\n## How it works\n\n```\nYour data / user context\n        │\n        ▼\n  [Backend AI agent]  ──generates──▶  DashboardSpec JSON\n                                              │\n                                              ▼\n                                  <DashboardRenderer data={spec} />\n                                              │\n                                              ▼\n                                    Interactive dashboard UI\n```\n\n1. **Backend agent** (`divami-labs-experiential-ui-agent`) — an optional Python package that takes your raw data and a user role, then uses an LLM to produce the `DashboardSpec` JSON automatically. See [Generating JSON with the AI agent](#generating-json-with-the-ai-agent).\n2. **Frontend renderer** (`@divami-labs/experiential-ui`) — this package. Pass any valid `DashboardSpec` JSON and it renders the dashboard. You can also hand-write the JSON yourself without the agent.\n\n---\n\n## Table of contents\n\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [Generating JSON with the AI agent](#generating-json-with-the-ai-agent)\n- [DashboardRenderer props](#dashboardrenderer-props)\n- [Standalone Chart component](#standalone-chart-component)\n  - [Single chart](#single-chart)\n  - [Multiple interacting charts](#multiple-interacting-charts)\n- [DashboardSpec schema](#dashboardspec-schema)\n  - [CardWidget](#cardwidget)\n  - [ChartWidget](#chartwidget)\n  - [TableWidget](#tablewidget)\n  - [ListWidget](#listwidget)\n- [Cross-widget interactivity](#cross-widget-interactivity)\n- [Drilldown navigation](#drilldown-navigation)\n- [Theming](#theming)\n  - [Theme tokens](#theme-tokens)\n  - [Component-level overrides](#component-level-overrides)\n  - [Applying a custom theme](#applying-a-custom-theme)\n- [TypeScript types](#typescript-types)\n- [Build and publish](#build-and-publish)\n\n---\n\n## Installation\n\n```bash\n# npm\nnpm install @divami-labs/experiential-ui react-plotly.js plotly.js\n\n# yarn\nyarn add @divami-labs/experiential-ui react-plotly.js plotly.js\n\n# pnpm\npnpm add @divami-labs/experiential-ui react-plotly.js plotly.js\n```\n\n**Peer dependencies** — install alongside the package:\n\n| Package | Version |\n|---------|---------|\n| `react` | ≥ 18 |\n| `react-dom` | ≥ 18 |\n| `plotly.js` | ≥ 2 |\n| `react-plotly.js` | ≥ 2 |\n\n---\n\n## Quick start\n\n```tsx\nimport { DashboardRenderer } from '@divami-labs/experiential-ui';\nimport '@divami-labs/experiential-ui/styles';\nimport type { DashboardSpec } from '@divami-labs/experiential-ui';\n\nconst spec: DashboardSpec = {\n  title: 'Sales Overview',\n  subtitle: 'Q1 2026 · AI-generated',\n  sections: [\n    {\n      cols: 3,\n      widgets: [\n        {\n          type: 'card',\n          title: 'Revenue',\n          metrics: [\n            { label: 'MRR',   value: '$128K', trend: 'up', change: '+18%' },\n            { label: 'Churn', value: '2.1%',  trend: 'up', change: '-0.4%' },\n          ],\n        },\n        {\n          type: 'chart',\n          title: 'Monthly Revenue',\n          chartType: 'bar',\n          labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],\n          values: [92, 97, 104, 112, 121, 128],\n          unit: 'K',\n        },\n        {\n          type: 'list',\n          title: 'Top Deals',\n          style: 'kv',\n          items: [\n            { label: 'Acme Corp',  value: '$48,000' },\n            { label: 'Globex Inc', value: '$32,500' },\n          ],\n        },\n      ],\n    },\n  ],\n};\n\nexport default function App() {\n  return <DashboardRenderer data={spec} />;\n}\n```\n\n> **CSS** — always import `'@divami-labs/experiential-ui/styles'` once in your app entry point. Without it, no design tokens or component styles will apply.\n\n---\n\n## Generating JSON with the AI agent\n\nInstead of writing the `DashboardSpec` JSON by hand, you can use the companion Python package **`divami-labs-experiential-ui-agent`**. It takes your raw data and a user role, calls an LLM, and returns a ready-to-render `DashboardSpec` — no manual JSON authoring needed.\n\nThe agent is built on [pydantic-ai](https://ai.pydantic.dev/models/), so the `model` parameter accepts any **pydantic-ai model string** — bring your own provider (Google, OpenAI, Anthropic, Mistral, and more). See the full list of supported model strings in the [pydantic-ai models documentation](https://ai.pydantic.dev/models/).\n\n**Requires Python ≥ 3.11.**\n\n### Install the backend package\n\n```bash\n# Google Gemini\npip install \"divami-labs-experiential-ui-agent[google]\"\n\n# OpenAI\npip install \"divami-labs-experiential-ui-agent[openai]\"\n\n# Both providers + Logfire observability\npip install \"divami-labs-experiential-ui-agent[all]\"\n```\n\nSet the matching API key in your environment:\n\n| Provider | pydantic-ai model string | Env var |\n|----------|--------------------------|---------|\n| Google Gemini | `google-gla:gemini-2.0-flash` | `GOOGLE_API_KEY` |\n| OpenAI | `openai:gpt-4o` | `OPENAI_API_KEY` |\n| Logfire observability | — | `LOGFIRE_TOKEN` |\n\n### Generate a dashboard spec\n\n```python\nfrom dynamic_ui import generate_dashboard, DashboardSpec\n\n# The `model` string follows pydantic-ai conventions: \"<provider>:<model-name>\"\n# Full list: https://ai.pydantic.dev/models/\nspec: DashboardSpec = await generate_dashboard(\n    model=\"google-gla:gemini-2.0-flash\",   # or \"openai:gpt-4o\", \"anthropic:claude-3-5-sonnet\", etc.\n    context={\n        \"sales\": [...],   # your raw data\n        \"emails\": [...],\n    },\n    user_role=\"VP of Sales\",\n    user_persona=\"Prefers high-level KPI cards before detailed charts.\",\n    user_prompt=\"What are my top priorities today?\",  # optional\n)\n\n# spec.model_dump() returns a plain dict — pass it straight to the frontend\npayload = spec.model_dump()\n```\n\n### Serve it from a FastAPI endpoint\n\n```python\nfrom fastapi import FastAPI\nfrom dynamic_ui import generate_dashboard\n\napp = FastAPI()\n\n@app.post(\"/dashboard\")\nasync def create_dashboard(role: str, context: dict) -> dict:\n    spec = await generate_dashboard(\n        model=\"openai:gpt-4o\",   # any pydantic-ai model string\n        context=context,\n        user_role=role,\n    )\n    return spec.model_dump()\n```\n\nThen fetch and render on the frontend:\n\n```tsx\nconst res  = await fetch('/dashboard', { method: 'POST', body: JSON.stringify({ role, context }) });\nconst spec = await res.json();\n\n<DashboardRenderer data={spec} />\n```\n\n> **Backend README** — full documentation for the Python package lives in [`backend/package/README.md`](https://github.com/divamidesignlabs/ai-experiential-ui-and-agent/blob/main/backend/package/README.md).\n\n---\n\n## DashboardRenderer props\n\n```tsx\n<DashboardRenderer\n  data={spec}           // required\n  theme={myTheme}       // optional — Partial<Theme>\n  rootClassName=\"...\"   // optional — extra class(es) on the root wrapper\n  onResolve={fn}        // optional — async page resolver for drilldowns\n/>\n```\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `data` | `DashboardSpec` | — | **Required.** Dashboard JSON to render. |\n| `theme` | `Partial<Theme>` | dark theme | Override any theme tokens or component styles. |\n| `rootClassName` | `string` | `''` | Extra class names on the `.dui-root` wrapper. |\n| `onResolve` | `PageResolver` | — | Loads a `DashboardSpec` by `pageId` for drilldown navigation. |\n\n---\n\n## Standalone Chart component\n\nUse `Chart` and `ChartProvider` independently of `DashboardRenderer` — embed charts anywhere in your app without a full dashboard layout.\n\n| Scenario | What to use |\n|---|---|\n| Single chart, no cross-chart interaction | `<Chart>` directly |\n| Multiple charts that interact with each other | `<ChartProvider>` wrapping them |\n| Full dashboard layout | `<DashboardRenderer>` |\n\n---\n\n### Example 1 — without interaction\n\nA single `<Chart>` with no providers. It renders a static chart; clicking has no effect on other components.\n\n```tsx\nimport { Chart } from '@divami-labs/experiential-ui';\nimport '@divami-labs/experiential-ui/styles';\nimport type { ChartWidget } from '@divami-labs/experiential-ui';\n\nconst revenueChart: ChartWidget = {\n  type: 'chart',\n  title: 'Monthly Revenue',\n  chartType: 'bar',\n  labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],\n  values: [92, 97, 104, 112, 121, 128],\n  unit: 'K',\n};\n\nexport default function RevenueWidget() {\n  return (\n    <div style={{ width: '100%', height: 320 }}>\n      <Chart widget={revenueChart} />\n    </div>\n  );\n}\n```\n\nNo context or provider required. Drop it anywhere.\n\n---\n\n### Example 2 — with interaction\n\nWrap multiple `<Chart>` components in a single `<ChartProvider>`. Charts linked by matching `broadcastOn` / `listenTo` keys will react to each other when clicked — the same mechanism that powers cross-widget selection inside a dashboard.\n\n```tsx\nimport { ChartProvider, Chart } from '@divami-labs/experiential-ui';\nimport '@divami-labs/experiential-ui/styles';\nimport type { ChartWidget } from '@divami-labs/experiential-ui';\n\n// Clicking a bar on this chart broadcasts the selected month\nconst revenueByMonth: ChartWidget = {\n  type: 'chart',\n  title: 'Revenue by Month',\n  chartType: 'bar',\n  broadcastOn: 'month-select',\n  dataset: [\n    { month: 'Jan', mrr: 92, starter: 40, pro: 35, enterprise: 17 },\n    { month: 'Feb', mrr: 97, starter: 38, pro: 37, enterprise: 22 },\n    { month: 'Mar', mrr: 104, starter: 36, pro: 38, enterprise: 30 },\n    { month: 'Apr', mrr: 112, starter: 34, pro: 40, enterprise: 38 },\n    { month: 'May', mrr: 121, starter: 32, pro: 42, enterprise: 47 },\n    { month: 'Jun', mrr: 128, starter: 30, pro: 43, enterprise: 55 },\n  ],\n  labelField: 'month',\n  valueField: 'mrr',\n  unit: 'K',\n};\n\n// This donut highlights the slice for the selected month\nconst planMix: ChartWidget = {\n  type: 'chart',\n  title: 'Plan Mix',\n  chartType: 'donut',\n  listenTo: 'month-select',\n  reactionMode: 'highlight',\n  dataset: revenueByMonth.dataset,\n  labelField: 'month',\n  series: [\n    { name: 'Starter',    field: 'starter' },\n    { name: 'Pro',        field: 'pro' },\n    { name: 'Enterprise', field: 'enterprise' },\n  ],\n};\n\nexport default function RevenueBreakdown() {\n  return (\n    // All charts inside one ChartProvider share the same selection state\n    <ChartProvider>\n      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>\n        <div style={{ height: 320 }}>\n          <Chart widget={revenueByMonth} />\n        </div>\n        <div style={{ height: 320 }}>\n          <Chart widget={planMix} />\n        </div>\n      </div>\n    </ChartProvider>\n  );\n}\n```\n\nClick any bar in the left chart — the donut on the right highlights the matching month's slice. Click the same bar again to deselect.\n\n> **Isolation** — each `<ChartProvider>` instance has its own selection state. Charts in separate providers never affect each other.\n\n---\n\n`Chart` props:\n\n| Prop | Type | Description |\n|------|------|-------------|\n| `widget` | `ChartWidget` | Full chart widget definition. |\n| `style` | `React.CSSProperties` | Optional inline styles on the container. |\n\n`ChartProvider` props:\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `children` | `ReactNode` | — | **Required.** Chart components to render. |\n| `theme` | `Partial<Theme>` | dark theme | Override any theme tokens or component styles. |\n| `className` | `string` | `''` | Extra class names on the `.dui-root` wrapper. |\n| `style` | `React.CSSProperties` | — | Inline styles on the `.dui-root` wrapper. |\n| `onResolve` | `PageResolver` | — | Async resolver for widget drilldown actions (`OPEN_MODAL` / `OPEN_OVERLAY` / `OPEN_PAGE`). Only needed if charts have `action` fields. |\n\n---\n\n## DashboardSpec schema\n\n```ts\ninterface DashboardSpec {\n  title?:    string;\n  subtitle?: string;\n  sections:  DashboardRow[];\n}\n\ninterface DashboardRow {\n  title?:   string;    // Section label\n  cols?:    number;    // Grid column count (default: widget count)\n  rows?:    number;    // Explicit row count for spanning widgets\n  widgets:  Widget[];  // card | chart | table | list\n}\n```\n\nEvery widget supports two layout properties:\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `colSpan` | `number` | Columns this widget spans (default `1`). |\n| `rowSpan` | `number` | Rows this widget spans (default `1`). |\n\n---\n\n### CardWidget\n\n```ts\ninterface CardWidget {\n  type:          'card';\n  id?:           string;\n  title?:        string;\n  content?:      string;\n  contentField?: string;\n  bullets?:      string[];\n  metrics?:      Metric[];\n  listenTo?:     string;\n  dataset?:      DataRecord[];\n  fieldMap?:     Record<string, string>; // { \"Display Label\": \"datasetField\" }\n  colSpan?:      number;\n  rowSpan?:      number;\n  action?:       WidgetAction;\n}\n\ninterface Metric {\n  label:   string;\n  value:   string | number;\n  unit?:   string;\n  trend?:  'up' | 'down' | 'neutral';\n  change?: string;\n}\n```\n\n```ts\n// Static KPI tiles\n{ type: 'card', title: 'Revenue',\n  metrics: [{ label: 'MRR', value: '$128K', trend: 'up', change: '+18%' }] }\n\n// Prose + bullets\n{ type: 'card', title: 'Summary',\n  content: 'Revenue grew 18% QoQ...',\n  bullets: ['Enterprise ARR crossed $10M', 'Churn at all-time low'] }\n\n// Dataset-driven — swaps metric values when a chart bar is clicked\n{ type: 'card', title: 'Month Detail',\n  listenTo: 'month-select',\n  dataset: [{ month: 'Jan', mrr: 92000, nps: 42 }, ...],\n  fieldMap: { 'MRR': 'mrr', 'NPS': 'nps' },\n  metrics: [{ label: 'MRR', value: '—' }, { label: 'NPS', value: '—' }] }\n```\n\n---\n\n### ChartWidget\n\n```ts\ninterface ChartWidget {\n  type:        'chart';\n  id?:         string;\n  title?:      string;\n  chartType:   ChartType;\n\n  // Static single-series\n  labels?:     string[];\n  values?:     number[];\n  totals?:     boolean[];\n  colors?:     string[];\n\n  // Static or dataset-driven multi-series\n  series?:     SeriesConfig[];\n\n  // Dataset-driven\n  dataset?:    DataRecord[];\n  labelField?: string;\n  valueField?: string;\n\n  unit?:       string;\n\n  // Interactivity\n  broadcastOn?:  string;\n  listenTo?:     string;\n  reactionMode?: 'highlight' | 'filter';\n\n  // CTA insert\n  insight?:  string;\n  ctaLabel?: string;\n  ctaHref?:  string;\n\n  colSpan?:  number;\n  rowSpan?:  number;\n  action?:   WidgetAction;\n}\n\ninterface SeriesConfig {\n  name:    string;\n  values?: number[];\n  field?:  string;\n  color?:  string;\n}\n```\n\n**Supported `ChartType` values:**\n\n| Value | Renders |\n|-------|---------|\n| `bar` | Vertical bar chart |\n| `bar_horizontal` | Horizontal bar chart |\n| `line` | Line / area chart |\n| `waterfall` | Waterfall bridge chart |\n| `stacked_bar` | Stacked bar (requires `series`) |\n| `grouped_bar` | Grouped bar (requires `series`) |\n| `pie` | Pie chart |\n| `donut` | Donut chart |\n| `scatter` | Scatter plot |\n| `funnel` | Funnel chart |\n\n```ts\n// Static bar\n{ type: 'chart', chartType: 'bar',\n  labels: ['Jan','Feb','Mar'], values: [92, 97, 104], unit: 'K' }\n\n// Dataset-driven multi-series line\n{ type: 'chart', chartType: 'line',\n  dataset: [{ month: 'Jan', actual: 92, target: 100 }, ...],\n  labelField: 'month',\n  series: [\n    { name: 'Actual', field: 'actual', color: '#6366f1' },\n    { name: 'Target', field: 'target', color: '#94a3b8' },\n  ] }\n\n// Broadcasts selection on click\n{ type: 'chart', chartType: 'bar_horizontal',\n  broadcastOn: 'region-select',\n  dataset: [{ region: 'APAC', revenue: 780000 }, ...],\n  labelField: 'region', valueField: 'revenue' }\n```\n\n---\n\n### TableWidget\n\n```ts\ninterface TableWidget {\n  type:          'table';\n  id?:           string;\n  title?:        string;\n  columns:       string[];\n  rows?:         (string | number | boolean | null)[][];\n  dataset?:      DataRecord[];\n  rowFields?:    string[];\n  listenTo?:     string;\n  reactionMode?: 'highlight' | 'filter';\n  colSpan?:      number;\n  rowSpan?:      number;\n  action?:       WidgetAction;\n}\n```\n\n```ts\n// Static rows\n{ type: 'table', columns: ['Account', 'ARR', 'Status'],\n  rows: [['Acme Corp', '$420K', 'Closed Won']] }\n\n// Dataset-driven, filters to the selected row on chart click\n{ type: 'table', listenTo: 'deal-select', reactionMode: 'filter',\n  dataset: [...], rowFields: ['account', 'arr', 'status'],\n  columns: ['Account', 'ARR', 'Status'] }\n```\n\n---\n\n### ListWidget\n\n```ts\ninterface ListWidget {\n  type:     'list';\n  id?:      string;\n  title?:   string;\n  style?:   'bullet' | 'numbered' | 'kv' | 'badge';\n  items:    ListItem[];\n  colSpan?: number;\n  rowSpan?: number;\n  action?:  WidgetAction;\n}\n\ninterface ListItem {\n  label:        string;\n  value?:       string | number;\n  badge?:       string;\n  badgeColor?:  'green' | 'red' | 'yellow' | 'blue' | 'gray';\n  description?: string;\n  href?:        string;\n}\n```\n\n| `style` | Renders |\n|---------|---------|\n| `bullet` (default) | Arrow bullet list |\n| `numbered` | Numbered list |\n| `kv` | Key → Value pairs |\n| `badge` | Label with coloured badge pill |\n\n---\n\n## Cross-widget interactivity\n\nLink any chart, table, or card using string keys — no extra wiring needed. Works identically inside `<DashboardRenderer>` and `<ChartProvider>`.\n\n```\nchart (broadcastOn: \"key\")  ──click──▶  table (listenTo: \"key\")\n                                    ──click──▶  card  (listenTo: \"key\")\n                                    ──click──▶  chart (listenTo: \"key\")\n```\n\n```ts\n// 1. Chart emits \"month-select\" when a bar is clicked\n{\n  type: 'chart', chartType: 'bar',\n  broadcastOn: 'month-select',\n  dataset: [...], labelField: 'month', valueField: 'mrr',\n}\n\n// 2. Card swaps its metrics when a month is selected\n{\n  type: 'card', title: 'Month Snapshot',\n  listenTo: 'month-select',\n  dataset: [...],\n  fieldMap: { 'MRR': 'mrr', 'NPS': 'nps' },\n  metrics: [{ label: 'MRR', value: '—' }, { label: 'NPS', value: '—' }],\n}\n\n// 3. Table highlights the matching row\n{\n  type: 'table', listenTo: 'month-select', reactionMode: 'highlight',\n  dataset: [...], rowFields: ['month', 'mrr', 'nps'],\n  columns: ['Month', 'MRR', 'NPS'],\n}\n```\n\n---\n\n## Drilldown navigation\n\nAdd an `action` to any widget to open a modal, side panel, or new tab on click.\n\n```ts\ntype WidgetAction =\n  | { action: 'OPEN_MODAL';   target: NavigationTarget; width?: string; height?: string }\n  | { action: 'OPEN_OVERLAY'; target: NavigationTarget; width?: string }\n  | { action: 'OPEN_PAGE';    target: NavigationTarget }\n\ninterface NavigationTarget {\n  spec?:   DashboardSpec;  // Inline drilldown spec\n  pageId?: string;         // Loaded via onResolve\n  title?:  string;\n  params?: Record<string, string | number | boolean>;\n}\n```\n\n```ts\n// Modal with an inline drilldown dashboard\n{\n  type: 'card', title: 'Revenue',\n  metrics: [...],\n  action: {\n    action: 'OPEN_MODAL', width: '800px',\n    target: {\n      title: 'Revenue Deep Dive',\n      spec: { sections: [{ widgets: [{ type: 'chart', chartType: 'line', ... }] }] },\n    },\n  },\n}\n\n// Side panel loaded dynamically via onResolve\n{\n  type: 'table', title: 'Deals',\n  rows: [...],\n  action: {\n    action: 'OPEN_OVERLAY', width: '520px',\n    target: { pageId: 'deal-detail', title: 'Deal Detail' },\n  },\n}\n```\n\n```tsx\nasync function myResolver(pageId, params) {\n  const res = await fetch(`/api/pages/${pageId}`);\n  return res.json(); // DashboardSpec\n}\n\n<DashboardRenderer data={spec} onResolve={myResolver} />\n```\n\n---\n\n## Theming\n\nThe renderer ships a **dark theme** by default and is fully self-contained.\nPass any `Partial<Theme>` to `theme` to override individual tokens.\n\n### Theme tokens\n\n```ts\ninterface Theme {\n  primary:      string;  // Accent colour — default '#6366f1'\n  primaryDark:  string;\n  primaryLight: string;\n  secondary:    string;\n\n  success:      string;\n  successLight: string;\n  warning:      string;\n  warningLight: string;\n  danger:       string;\n  dangerLight:  string;\n\n  gray50:  string;  // Page background\n  gray100: string;  // Subtle surface\n  gray200: string;  // Borders\n  gray300: string;\n  gray400: string;\n  gray500: string;\n  gray600: string;\n  gray700: string;\n  gray800: string;\n  gray900: string;\n\n  fontFamily: string;  // e.g. \"'Inter', sans-serif\"\n  radius:     string;  // Widget border-radius\n  radiusSm:   string;\n\n  sectionGap:          string;\n  widgetGap:           string;\n  widgetHeaderPadding: string;\n  widgetBodyPadding:   string;\n  dashboardPadding:    string;\n\n  shadowSm: string;\n  shadow:   string;\n  shadowLg: string;\n\n  components?: ComponentStyles;  // Per-element overrides\n}\n```\n\n> **Light vs dark detection** — the renderer sets `data-theme=\"light\"` or `\"dark\"` automatically based on whether `gray50` is a light colour (starts with `#F` or `#f`).\n\n### Component-level overrides\n\nEvery structural element accepts a `StyleSlot` (`className?` + `style?`) under `theme.components`:\n\n`widget` · `widgetHeader` · `widgetBody` · `section` · `sectionTitle` · `metricTile` · `metricsGrid` · `cardContent` · `cardBullets` · `table` · `tableHeader` · `tableCell` · `list` · `listItem` · `chartContainer`\n\n### Applying a custom theme\n\n```tsx\nimport { DashboardRenderer } from '@divami-labs/experiential-ui';\nimport type { Theme } from '@divami-labs/experiential-ui';\nimport '@divami-labs/experiential-ui/styles';\n\nconst warmTheme: Partial<Theme> = {\n  primary:      '#f59e0b',\n  primaryDark:  '#d97706',\n  primaryLight: 'rgba(245, 158, 11, 0.12)',\n  secondary:    '#fb923c',\n\n  // Light cream background\n  gray50:  '#fdfaf5',\n  gray100: '#f5f0e8',\n  gray200: '#e8dfc8',\n  gray900: '#1a1508',\n\n  fontFamily: \"'Inter', 'Helvetica Neue', Arial, sans-serif\",\n  radius:     '4px',\n  radiusSm:   '2px',\n\n  components: {\n    widget: {\n      style: { background: '#ffffff', border: '1px solid #e8dfc8' },\n    },\n    widgetHeader: {\n      style: { background: '#fffdf7', borderBottom: '2px solid #f59e0b' },\n    },\n  },\n};\n\nexport default function App() {\n  return <DashboardRenderer data={spec} theme={warmTheme} />;\n}\n```\n\n---\n\n## TypeScript types\n\n```ts\nimport type {\n  // Data model\n  DashboardSpec, DashboardRow,\n  Widget, CardWidget, ChartWidget, ChartType, SeriesConfig,\n  TableWidget, ListWidget, ListItem, ListVariant,\n  Metric, DataRecord, WidgetAction,\n\n  // Component props\n  DashboardRendererProps, ChartProviderProps, ChartProps,\n\n  // Theming\n  Theme, ComponentStyles, StyleSlot,\n} from '@divami-labs/experiential-ui';\n```\n\n---\n\n## Build and publish\n\n```bash\n# Build library (ESM + CJS + types + CSS)\nnpm run build:lib\n\n# Pack for local testing\nnpm pack\n\n# Publish to npm (build:lib runs automatically via prepublishOnly)\nnpm publish\n```\n\n---\n\n## License\n\nMIT © [Divami Design Labs](https://github.com/divamidesignlabs)","readmeFilename":"README.md"}