{"_id":"@aiera-inc/react-slots","_rev":"6-9c9c1f0d2b3ba8b268f0b288f154d9da","name":"@aiera-inc/react-slots","dist-tags":{"beta-0.1.0":"0.1.0","beta":"0.1.1","latest":"0.3.1"},"versions":{"0.1.0":{"name":"@aiera-inc/react-slots","version":"0.1.0","keywords":["react","slots","ui","frontend","typescript","javascript","utility"],"author":{"name":"Aiera Inc."},"license":"MIT","_id":"@aiera-inc/react-slots@0.1.0","maintainers":[{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},{"name":"elliotnash","email":"elliot@aiera.com"},{"name":"bcantello","email":"brandon.cantello@aiera.com"},{"name":"bhealey","email":"bryan@aiera.com"},{"name":"vich-aiera","email":"michael@aiera.com"}],"homepage":"https://github.com/aiera-inc/react-slots#readme","bugs":{"url":"https://github.com/aiera-inc/react-slots/issues"},"dist":{"shasum":"c699486e4b478a4b78adf75283ee68b5d5d9b545","tarball":"https://registry.npmjs.org/@aiera-inc/react-slots/-/react-slots-0.1.0.tgz","fileCount":6,"integrity":"sha512-ol4Nlq46JGYEgTA2A9x2SC5U8q8h6vQpX3NeMXiNL9O8CLgMdUl6Ok0b/p+WIloI9ofUb6EMc2MmmljOAi5PyQ==","signatures":[{"sig":"MEYCIQCl/tLTH1PENFRwSqaAX06TNHUEYllu8m/Th2/wxJXFLwIhAOhXmTUMlTA5LeTUlnH6PvNwuahvoahgzDkY1qJcT+yP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26050},"main":"dist/react-slots.js","type":"module","types":"dist/react-slots.d.ts","exports":{".":{"types":"./dist/react-slots.d.ts","import":"./dist/react-slots.js"}},"gitHead":"dac6408424c28e484f32c0cfaa06c59816319cdd","scripts":{"fmt":"prettier --write .","lint":"eslint .","test":"jest","build":"node ./build.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},"prettier":{"semi":true,"tabWidth":2,"printWidth":100,"singleQuote":true,"trailingComma":"all"},"repository":{"url":"git+https://github.com/aiera-inc/react-slots.git","type":"git"},"_npmVersion":"11.3.0","description":"A simple utility for adding named slots to React components, inspired by the slot pattern in Vue.","directories":{"example":"example"},"_nodeVersion":"24.0.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","tslib":"^2.8.1","eslint":"^9.26.0","esbuild":"^0.25.4","ts-jest":"^29.3.3","prettier":"^3.5.3","@eslint/js":"^9.26.0","typescript":"^5.8.3","@types/jest":"^29.5.14","expect-type":"^1.2.1","@types/react":"18.2.0","typescript-eslint":"^8.32.1","esbuild-plugin-tsc":"^0.5.0","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.2.0"},"peerDependencies":{"react":"18.2.0","react-dom":"18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/react-slots_0.1.0_1747614154368_0.8523633891178688","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aiera-inc/react-slots","version":"0.1.1","keywords":["react","slots","ui","frontend","typescript","javascript","utility"],"author":{"name":"Aiera Inc."},"license":"MIT","_id":"@aiera-inc/react-slots@0.1.1","maintainers":[{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},{"name":"elliotnash","email":"elliot@aiera.com"},{"name":"bcantello","email":"brandon.cantello@aiera.com"},{"name":"bhealey","email":"bryan@aiera.com"},{"name":"vich-aiera","email":"michael@aiera.com"}],"homepage":"https://github.com/aiera-inc/react-slots#readme","bugs":{"url":"https://github.com/aiera-inc/react-slots/issues"},"dist":{"shasum":"09b2f5c99e3931965086455b51e43a66f620ef8a","tarball":"https://registry.npmjs.org/@aiera-inc/react-slots/-/react-slots-0.1.1.tgz","fileCount":5,"integrity":"sha512-+Uxelu9jHT/Y8EsAJAA4T35j6azhiVJnALkXZAntr/apuAudeLPZYUFprarBL/EkV+rD3VnRRxc9w/3lsYQltg==","signatures":[{"sig":"MEUCIQD4lUYvIH6nVmthf2W2A6BJPTSYhs/Wu5OYHH+dJCTUZgIgJCwfG50RmYA/Y2vDu6guWMKeY83pgtG1w0V+66NcGdM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16263},"main":"dist/react-slots.js","type":"module","types":"dist/react-slots.d.ts","exports":{".":{"types":"./dist/react-slots.d.ts","import":"./dist/react-slots.js"}},"gitHead":"5f2706427387d12ff2b352336ccdc45b33433577","scripts":{"fmt":"prettier --write .","lint":"eslint .","test":"jest","build":"rm -rf ./dist & npm run build:main & npm run build:types","build:main":"node ./build.js","build:types":"tsc --declaration --emitDeclarationOnly --outDir dist","prepublishOnly":"npm run build"},"_npmUser":{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},"prettier":{"semi":true,"tabWidth":2,"printWidth":100,"singleQuote":true,"trailingComma":"all"},"repository":{"url":"git+https://github.com/aiera-inc/react-slots.git","type":"git"},"_npmVersion":"11.3.0","description":"A simple utility for adding named slots to React components, inspired by the slot pattern in Vue.","directories":{"example":"example"},"_nodeVersion":"24.0.2","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","tslib":"^2.8.1","eslint":"^9.26.0","esbuild":"^0.25.4","ts-jest":"^29.3.3","prettier":"^3.5.3","@eslint/js":"^9.26.0","typescript":"^5.8.3","@types/jest":"^29.5.14","expect-type":"^1.2.1","@types/react":"18.2.0","typescript-eslint":"^8.32.1","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.2.0"},"peerDependencies":{"react":"18.2.0","react-dom":"18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/react-slots_0.1.1_1747615686659_0.08474104481491818","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@aiera-inc/react-slots","version":"0.1.2","keywords":["react","slots","react-slots","ui","ui-components","frontend","typescript","javascript","utility","component","composition","lib","library","aiera","aiera-inc","@aiera","@aiera-inc","aiera-inc/react-slots"],"author":{"name":"Aiera Inc."},"license":"MIT","_id":"@aiera-inc/react-slots@0.1.2","maintainers":[{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},{"name":"elliotnash","email":"elliot@aiera.com"},{"name":"bcantello","email":"brandon.cantello@aiera.com"},{"name":"bhealey","email":"bryan@aiera.com"},{"name":"vich-aiera","email":"michael@aiera.com"}],"homepage":"https://github.com/aiera-inc/react-slots#readme","bugs":{"url":"https://github.com/aiera-inc/react-slots/issues"},"dist":{"shasum":"4bfc49f3b676819b4fae38b282780739b13077f9","tarball":"https://registry.npmjs.org/@aiera-inc/react-slots/-/react-slots-0.1.2.tgz","fileCount":5,"integrity":"sha512-KQY30tDQJdv1uOE4EX4Tw40pJH7IupfiFIidXEMPBLvS4x/AczrmhA8GKH2KIV2cDVDKFqrcalZcRKC9hmmFFg==","signatures":[{"sig":"MEYCIQCs1uLIRP82tDv0KDbhXmyQNRdaetQTQK3f/b8kZRM0jQIhANVqhZ3E4pk7vfYtadHqPU+emNnxqhfD+0uehRSrtIrC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16797},"main":"dist/react-slots.js","type":"module","types":"dist/react-slots.d.ts","exports":{".":{"types":"./dist/react-slots.d.ts","import":"./dist/react-slots.js"}},"gitHead":"1053db1406f80cad3aafd966ab196b13e2c04c97","scripts":{"fmt":"prettier --write .","lint":"eslint .","test":"jest","build":"rm -rf ./dist & npm run build:main & npm run build:types","prepare":"husky","build:main":"node ./build.js","build:types":"tsc --declaration --emitDeclarationOnly --outDir dist","prepublishOnly":"npm run build"},"_npmUser":{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},"prettier":{"semi":true,"tabWidth":2,"printWidth":100,"singleQuote":true,"trailingComma":"all"},"repository":{"url":"git+https://github.com/aiera-inc/react-slots.git","type":"git"},"_npmVersion":"11.3.0","description":"A simple utility for adding named slots to React components, inspired by the slot pattern in Vue.","directories":{"example":"example"},"lint-staged":{"*.md":["prettier --write"],"*.json":["prettier --write"],"*.{js,jsx,ts,tsx}":["eslint --fix","prettier --write"]},"_nodeVersion":"24.0.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","husky":"^9.1.7","tslib":"^2.8.1","eslint":"^9.26.0","esbuild":"^0.25.4","ts-jest":"^29.3.3","prettier":"^3.5.3","@eslint/js":"^9.26.0","typescript":"^5.8.3","@types/jest":"^29.5.14","expect-type":"^1.2.1","lint-staged":"^16.1.0","@types/react":"18.2.0","typescript-eslint":"^8.32.1","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.2.0"},"peerDependencies":{"react":"18.2.0","react-dom":"18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/react-slots_0.1.2_1748912702726_0.17638034969785465","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@aiera-inc/react-slots","version":"0.1.3","keywords":["react","slots","react-slots","ui","ui-components","frontend","typescript","javascript","utility","component","composition","lib","library","aiera","aiera-inc","@aiera","@aiera-inc","aiera-inc/react-slots"],"author":{"name":"Aiera Inc."},"license":"MIT","_id":"@aiera-inc/react-slots@0.1.3","maintainers":[{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},{"name":"elliotnash","email":"elliot@aiera.com"},{"name":"bcantello","email":"brandon.cantello@aiera.com"},{"name":"bhealey","email":"bryan@aiera.com"},{"name":"vich-aiera","email":"michael@aiera.com"}],"homepage":"https://github.com/aiera-inc/react-slots#readme","bugs":{"url":"https://github.com/aiera-inc/react-slots/issues"},"dist":{"shasum":"0f864665fa038831723ff0ba8469b9bae83dd26e","tarball":"https://registry.npmjs.org/@aiera-inc/react-slots/-/react-slots-0.1.3.tgz","fileCount":5,"integrity":"sha512-5iTv6B/b3UKA12nOFhAf2/g7+jSvqgNyTeFsUT8yaijnk9emojQBKecjVx3PWDQJTHcBTRqiUbMmYRQfUjFtAg==","signatures":[{"sig":"MEUCIAJZMOvo2kaGcQs4G5qqJzC/lhO/mhUJDa/MvSsXpegJAiEAmdyToHyHbFKYSxrrxmB4d8O2Q6DkhY4fdkFxLIYjQhQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17732},"main":"dist/react-slots.js","type":"module","types":"dist/react-slots.d.ts","exports":{".":{"types":"./dist/react-slots.d.ts","import":"./dist/react-slots.js"}},"gitHead":"e4d20a914a1ae10f67aa73b76f8692046e2ded22","scripts":{"fmt":"prettier --write .","lint":"eslint .","test":"jest","build":"rm -rf ./dist & npm run build:main & npm run build:types","prepare":"husky","build:main":"node ./build.js","build:types":"tsc --declaration --emitDeclarationOnly --outDir dist"},"_npmUser":{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},"prettier":{"semi":true,"tabWidth":2,"printWidth":100,"singleQuote":true,"trailingComma":"all"},"repository":{"url":"git+https://github.com/aiera-inc/react-slots.git","type":"git"},"_npmVersion":"11.3.0","description":"A simple utility for adding named slots to React components, inspired by the slot pattern in Vue.","directories":{"example":"example"},"lint-staged":{"*.md":["prettier --write"],"*.json":["prettier --write"],"*.{js,jsx,ts,tsx}":["eslint --fix","prettier --write"]},"_nodeVersion":"24.0.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","husky":"^9.1.7","tslib":"^2.8.1","eslint":"^9.26.0","esbuild":"^0.25.4","ts-jest":"^29.3.3","prettier":"^3.5.3","@eslint/js":"^9.26.0","typescript":"^5.8.3","@types/jest":"^29.5.14","expect-type":"^1.2.1","lint-staged":"^16.1.0","@types/react":"18.2.0","typescript-eslint":"^8.32.1","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.2.0"},"peerDependencies":{"react":"18.2.0","react-dom":"18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/react-slots_0.1.3_1748996727505_0.49468800290813264","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aiera-inc/react-slots","version":"0.3.1","description":"A simple utility for adding named slots to React components, inspired by the slot pattern in Vue.","keywords":["react","slots","react-slots","named-slots","vue-slots","children","compound-components","render-slots","ui-components","frontend","typescript","utility","component","composition","aiera","aiera-inc"],"homepage":"https://github.com/aiera-inc/react-slots#readme","bugs":{"url":"https://github.com/aiera-inc/react-slots/issues"},"repository":{"type":"git","url":"git+https://github.com/aiera-inc/react-slots.git"},"license":"MIT","author":{"name":"Aiera Inc."},"type":"module","exports":{".":{"import":"./dist/react-slots.js","types":"./dist/react-slots.d.ts"},"./server":{"import":"./dist/react-slots-server.js","types":"./dist/react-slots-server.d.ts"}},"main":"dist/react-slots.js","types":"dist/react-slots.d.ts","directories":{"example":"example"},"scripts":{"test":"jest","typecheck":"npm run typecheck:react-18 && npm run typecheck:react-19","typecheck:react-18":"tsc --project test-envs/react-18/tsconfig.json","typecheck:react-19":"tsc --project test-envs/react-19/tsconfig.json","test:all":"npm run typecheck && npm test","build":"rm -rf ./dist && npm run build:main & npm run build:types & wait","build:main":"node ./build.js","build:types":"tsc --declaration --emitDeclarationOnly --outDir dist","lint":"eslint .","fmt":"prettier --write .","prepublishOnly":"npm run build","prepare":"husky"},"devDependencies":{"@eslint/js":"^9.26.0","@testing-library/jest-dom":"^6.6.3","@testing-library/react":"^16.3.0","@types/jest":"^29.5.14","@types/react":"^18.2.8","esbuild":"^0.25.4","eslint":"^9.26.0","eslint-plugin-react-hooks":"^5.2.0","expect-type":"^1.2.1","husky":"^9.1.7","jest":"^29.7.0","jest-environment-jsdom":"^29.7.0","lint-staged":"^16.1.0","prettier":"^3.5.3","ts-jest":"^29.3.3","tslib":"^2.8.1","typescript":"^5.8.3","typescript-eslint":"^8.32.1"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0"},"prettier":{"singleQuote":true,"semi":true,"trailingComma":"all","tabWidth":2,"printWidth":100},"publishConfig":{"registry":"https://registry.npmjs.org/","access":"public"},"lint-staged":{"*.{js,jsx,ts,tsx}":["eslint --fix","prettier --write"],"*.json":["prettier --write"],"*.md":["prettier --write"]},"gitHead":"b09acd9f534634d9d4a9e60f0fda40e62a3d4918","_id":"@aiera-inc/react-slots@0.3.1","_nodeVersion":"25.0.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-UYqoP9QZCYNiZzlZrdoG/lv2S5rgoxVf0Wac7tUFWNB7p8zMj/uHnv/UeHYJTeQRhs/xOG0FQavPo3aYNKB57Q==","shasum":"13e1e689631bdd200bbd352d0314957e03dc0607","tarball":"https://registry.npmjs.org/@aiera-inc/react-slots/-/react-slots-0.3.1.tgz","fileCount":7,"unpackedSize":22936,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIF2e6un0+mQN6CrkU4sc2io8VrNvGmxRnMwN3wFzXKkkAiEAwK8IPLFf2ZsuOdfQNVaXr06t9rR+h86AKyQpadGMyq0="}]},"_npmUser":{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},"maintainers":[{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},{"name":"elliotnash","email":"elliot@aiera.com"},{"name":"bcantello","email":"brandon.cantello@aiera.com"},{"name":"bhealey","email":"bryan@aiera.com"},{"name":"vich-aiera","email":"michael@aiera.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/react-slots_0.3.1_1775887224166_0.702048794706841"},"_hasShrinkwrap":false}},"time":{"created":"2025-05-19T00:22:34.238Z","modified":"2026-04-11T06:00:24.460Z","0.1.0":"2025-05-19T00:22:34.624Z","0.1.1":"2025-05-19T00:48:06.867Z","0.1.2":"2025-06-03T01:05:02.912Z","0.1.3":"2025-06-04T00:25:27.715Z","0.3.1":"2026-04-11T06:00:24.293Z"},"bugs":{"url":"https://github.com/aiera-inc/react-slots/issues"},"author":{"name":"Aiera Inc."},"license":"MIT","homepage":"https://github.com/aiera-inc/react-slots#readme","keywords":["react","slots","react-slots","named-slots","vue-slots","children","compound-components","render-slots","ui-components","frontend","typescript","utility","component","composition","aiera","aiera-inc"],"repository":{"type":"git","url":"git+https://github.com/aiera-inc/react-slots.git"},"description":"A simple utility for adding named slots to React components, inspired by the slot pattern in Vue.","maintainers":[{"name":"bsickler-aiera","email":"burton.sickler@aiera.com"},{"name":"elliotnash","email":"elliot@aiera.com"},{"name":"bcantello","email":"brandon.cantello@aiera.com"},{"name":"bhealey","email":"bryan@aiera.com"},{"name":"vich-aiera","email":"michael@aiera.com"}],"readme":"# react-slots\n\nA simple utility for adding named slots to React components, inspired by the slot pattern in web components and Vue.\n\n## Features\n\n- **Named slots**: Expand on React's children by defining specific child component options.\n- **Structured layout**: Assign your slot components to static locations in the JSX.\n- **Multiple/Repeatable slots**: Allow multiple children for a slot by wrapping the slot component in an array.\n- **Composed components**: Add components to the namespace without rendering them as slots.\n- **TypeScript support**: Strongly typed slot schemas and props.\n- **React Server Component support**: Use `getSlots` in server components via the `/server` entry point.\n- **Dev-mode warnings**: Actionable console warnings for common mistakes like duplicate slots and schema mismatches.\n- **React 18 & 19**: Works with both React ^18 and ^19.\n- **Tiny bundle size**: 2.3kb client / 1.8kb server.\n\n**[Try it on StackBlitz](https://stackblitz.com/github/aiera-inc/react-slots/tree/main/example?file=my-component.tsx)**\n\n## Installation\n\n```\nnpm i @aiera-inc/react-slots\n```\n\n## Usage\n\nSlotted components are created using the `SlottedComponent` utility method exported by the library and consumed just like any other React component.\n\n```tsx\nimport { SlottedComponent } from '@aiera-inc/react-slots';\n\n// Your parent components props\ntype MyComponentProps = {\n  author: string;\n};\n\n// The components you are assigning as slots\nconst SLOT_SCHEMA = {\n  Title: (props: { title: string }) => <header>{props.title}</header>,\n  Footer: () => <footer>Footer</footer>,\n} as const;\n\n// Your slotted component\nexport const MyComponent = SlottedComponent(SLOT_SCHEMA)<MyComponentProps>(({\n  author,\n  children,\n  slots: { Title, Footer },\n}) => {\n  return (\n    <div>\n      {Title}\n      <h3>By: {author}</h3>\n      <main>{children}</main>\n      {Footer}\n    </div>\n  );\n});\n```\n\n### Using Your Component\n\nYour slotted component works like any other React component, only it now has several slots added as properties to it.\n\n```tsx\nimport { MyComponent } from './my-component';\n\nexport function App() {\n  return (\n    <div>\n      <MyComponent author=\"John Doe\">\n        <MyComponent.Title title=\"Hello World\" />\n        <article>This is the main content.</article>\n        <article>A second article.</article>\n        <MyComponent.Footer />\n      </MyComponent>\n    </div>\n  );\n}\n```\n\nNote, the order of the slotted child components doesn't actually matter because the `MyComponent` code has placed it in a concrete location within its layout.\n\n```jsx\nfunction App() {\n  return (\n    <>\n      // This is equivalent...\n      <MyComponent author=\"John Doe\">\n        <MyComponent.Title title=\"Hello World\" />\n        <article>This is the main content.</article>\n        <article>A second article.</article>\n        <MyComponent.Footer />\n      </MyComponent>\n      // ...to this\n      <MyComponent author=\"John Doe\">\n        <MyComponent.Title title=\"Hello World\" />\n        <MyComponent.Footer />\n        <article>This is the main content.</article>\n        <article>A second article.</article>\n      </MyComponent>\n    </>\n  );\n}\n```\n\n## Features\n\nThe _slot schema_ has two unique syntax structures that can be used to define **repeated slots** and **namespace slots**.\n\n### Repeated Slots\n\nBy default, only one instance of a component will be passed to a slot and the others will be tossed.\n\n```tsx\nconst ArticleExample = (props) => <article>{props.children}</article>;\n\nconst SLOT_SCHEMA = {\n  Article: ArticleExample,\n} as const;\n\nconst Blog = SlottedComponent(SLOT_SCHEMA)<{ author: string }>(({\n  author,\n  children,\n  slots: { Article },\n}) => {\n  return <div>{Article}</div>;\n});\n\nfunction App() {\n  return (\n    <Blog author=\"John Doe\">\n      <Blog.Article>Article 1</Blog.Article>\n      <Blog.Article>Article 2</Blog.Article> // This will be ignored\n    </Blog>\n  );\n}\n```\n\nTo allow for repeated uses of a slot, you simply need to wrap it in square brackets in the slot schema. This tells the utility that multiple instances of the `<Article />` slot may be passed and should be rendered.\n\n```tsx\nconst ArticleExample = (props) => <article>{props.children}</article>;\n\nconst SLOT_SCHEMA = {\n  Article: [ArticleExample],\n} as const;\n```\n\n### Namespaced Slots (Composed Components)\n\nSometimes you may want to link components to indicate a relationship between parent and child, but you don't have a concrete location that you want to place the children in your layout. You are effectively namespacing the child component to the parent. This is often also described as **composed components**.\n\n```tsx\nconst ArticleExample = (props) => <article>{props.children}</article>;\n\nconst SLOT_SCHEMA = {\n  // Wrapping the component in curly braces\n  Article: { ArticleExample }, // tells the utility this is a namespaced\n} as const; // component.\n\nconst Blog = SlottedComponent(SLOT_SCHEMA)<{ author: string }>(({\n  author,\n  children, // children contains your Article instances\n  slots, // Slots will be an empty object\n}) => {\n  return <div>{children}</div>;\n});\n\nfunction App() {\n  return (\n    <Blog author=\"John Doe\">\n      <Blog.Article>Article 1</Blog.Article>\n      <Blog.Article>Article 2</Blog.Article>\n    </Blog>\n  );\n}\n```\n\n## Server Components\n\nThe library provides a separate entry point for React Server Components that exports only the pure functions — no hooks, no `'use client'` boundary.\n\n```tsx\n// In a server component\nimport { getSlots } from '@aiera-inc/react-slots/server';\n\nexport function ServerLayout({ children }: { children: React.ReactNode }) {\n  const { slots, children: rest } = getSlots(children, schema);\n  return (\n    <div>\n      {slots.Header}\n      <main>{rest}</main>\n    </div>\n  );\n}\n```\n\nThe main entry point (`@aiera-inc/react-slots`) includes a `'use client'` directive and re-exports everything from the server module, plus the hook-based APIs.\n\n| Entry point                     | Exports                                                        | RSC-safe        |\n| ------------------------------- | -------------------------------------------------------------- | --------------- |\n| `@aiera-inc/react-slots`        | `getSlots`, `withSlots`, `SlottedComponent`, `useSlots`, types | No (uses hooks) |\n| `@aiera-inc/react-slots/server` | `getSlots`, types                                              | Yes             |\n\n## API Reference\n\n### `getSlots(children, schema)`\n\nUtility to extract slots and non-slot children from a component's children. This is a pure function with no hooks — safe for use in React Server Components via the `/server` entry point.\n\n### `withSlots(Parent, schema)`\n\nWraps your component and attaches slot components as static properties. The `slots` prop will be injected into your component, containing the slotted children. Client-only (uses hooks internally).\n\n### `SlottedComponent(schema)`\n\nHigher-order component for applying a slot schema in a more declarative way. Client-only (wraps `withSlots`).\n\n### `useSlots(children, schema)`\n\nReact hook that extracts slots from children with memoization. Client-only.\n\n```tsx\nimport { useSlots } from '@aiera-inc/react-slots';\n\nfunction MyComponent({ children }: { children?: React.ReactNode }) {\n  const { slots, children: rest } = useSlots(children, { Title, Footer });\n  return (\n    <div>\n      {slots.Title}\n      <main>{rest}</main>\n      {slots.Footer}\n    </div>\n  );\n}\n```\n\n## TypeScript Types\n\n- `SlotDictionary`: Defines the slot schema.\n- `SlotConstructor`: A narrowed component function type for slots.\n- `WithSlotProps<P, T>`: Utility type for merging slot props into your component props.\n- `SlotProviderInterface<T>`: Interface alternative for slot props.\n\n## Dev-Mode Warnings\n\nIn non-production environments, the library warns about common mistakes:\n\n- **Duplicate single-slot**: When multiple children match a single-slot, only the last is kept.\n- **Unmatched component**: When a function component child doesn't match any slot in the schema.\n- **Invalid schema**: When a schema key has an invalid value.\n\nWarnings are tree-shaken in production builds. The dev check works across Node, Deno, Bun, and Cloudflare Workers via `globalThis.process.env.NODE_ENV` with a `globalThis.__DEV__` fallback.\n\n## Notes\n\n- Fragments are recursively flattened, so slotted children are found regardless of nesting depth.\n- Namespaced slots are not included in the `slots` prop.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}