{"id":13671373,"url":"https://github.com/dschnare/react-slot","last_synced_at":"2025-04-27T18:31:06.606Z","repository":{"id":57344953,"uuid":"92081130","full_name":"dschnare/react-slot","owner":"dschnare","description":"Slot-based content distribution component for React","archived":false,"fork":false,"pushed_at":"2018-07-03T20:20:54.000Z","size":17,"stargazers_count":41,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T03:48:04.129Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dschnare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-22T17:35:23.000Z","updated_at":"2023-07-08T17:09:58.000Z","dependencies_parsed_at":"2022-09-11T09:00:40.646Z","dependency_job_id":null,"html_url":"https://github.com/dschnare/react-slot","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschnare%2Freact-slot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschnare%2Freact-slot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschnare%2Freact-slot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschnare%2Freact-slot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dschnare","download_url":"https://codeload.github.com/dschnare/react-slot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251187050,"owners_count":21549576,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T09:01:07.873Z","updated_at":"2025-04-27T18:31:06.330Z","avatar_url":"https://github.com/dschnare.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# React Slot\n\nSlot-based content distribution component for React. The technique was highly\ninfluenced by the content distribution techniques used by\n[Vuejs](http://vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots).\n\n## Install\n\n```shell\nnpm install react@\"\u003e=15\" react-dom@\"\u003e=15\" react-slot -S\n```\n\n## Quick Start\n\n```jsx\n/*\n  LayoutDefault.js\n  Generates a slotted HTML layout like the following:\n\n  \u003cdiv class=\"layout-default\"\u003e\n    \u003cheader class=\"slot-header\"\u003eWelcome!\u003c/header\u003e\n    \u003cdiv class=\"slot-default main\" role=\"main\"\u003e\u003c/div\u003e\n    \u003cdiv class=\"slot-info\"\u003eCopyright 2017\u003c/div\u003e\n    \u003cfooter class=\"slot-footer\"\u003e\u003c/footer\u003e\n  \u003c/div\u003e\n*/\nimport * as React from 'react'\nimport { Slot } from 'react-slot'\n\nexport default function LayoutDefault (props) {\n  const { children } = props\n  return (\n    \u003cdiv className='layout-default'\u003e\n      \u003cSlot name='header' as='header' content={children}\u003eWelcome!\u003c/Slot\u003e\n      \u003cSlot className='main' role='main' content={children} /\u003e\n      \u003cSlot name='info' content={children}\u003eCopyright 2017\u003c/Slot\u003e\n      \u003cSlot name='footer' as='footer' content={children} /\u003e\n    \u003c/div\u003e\n  )\n}\n\n/*\n  PageHome.js\n  Create a page that will insert content into a layout's slots.\n  Generates HTML like the following (depends on what layout is used):\n\n  \u003cdiv class=\"page-home\"\u003e\n    \u003cdiv class=\"layout-default\"\u003e\n      \u003cheader class=\"slot-header\"\u003e\u003ch1\u003eHome\u003c/h1\u003e\u003c/header\u003e\n      \u003cdiv class=\"slot-default main\" role=\"main\"\u003eThe main content\u003c/div\u003e\n      \u003cdiv class=\"slot-info\"\u003eCopyright 2017\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n*/\nimport * as React from 'react'\n\nexport default PageHome extends React.Component {\n  static propsTypes = {\n    layout: PropTypes.func.isRequired\n  }\n\n  render () {\n    const { layout } = this.props\n\n    return (\n      \u003cdiv className='page-home'\u003e\n        \u003clayout\u003e\n          \u003cdiv slot='header'\u003e\u003ch1\u003eHome\u003c/h1\u003e\u003c/div\u003e\n          \u003cdiv slot\u003e\n            The main content\n          \u003c/div\u003e\n        \u003c/layout\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n\n// App.js\nimport * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport PageHome from './PageHome'\n\nconst page = \u003cPageHome layout={DefaultLayout} /\u003e\n\nReactDOM.render(\n  page,\n  document.getElementById('app')\n)\n```\n\n## API\n\n### Slot\n\nSlot is a component that is meant to compose your layouts with. These act\nas the points where a layout can be altered by a parent using the layout\ncomponent. The slot without a name is known as the default slot.\n\n**Props**\n\n- `content` *[required]* The React children of the parent component\n- `children` The default content to render if no content is inserted from the parent component\n- `name` The name of this slot (inserted as class name 'slot-${name}')\n- `id` The HTML id\n- `className` Additional class names\n- `dataset` *[default: {}]* An object with keys to set as 'data-' attributes (keys must not contain a 'data-' prefix)\n- `role` The HTML role\n- `as` *[default: 'div']* The type of React element (string or function) to create the root element as\n\nSomething to keep in mind, Slot elements will render nothing if they don't have\nany default content and the parent component didn't insert any content.\n\n```jsx\n\u003cSlot name='my-slot' content={children} /\u003e\n```\n\nFull Example:\n\n```jsx\n/*\n  A layout that will render HTML like the following:\n\n  \u003cdiv class=\"layout-default\"\u003e\n    \u003cheader\u003eWelcome!\u003c/header\u003e\n    \u003cdiv class=\"slot-default main\" role=\"main\"\u003e\u003c/div\u003e\n    \u003cdiv class=\"slot-info\"\u003eCopyright 2017\u003c/div\u003e\n    \u003cfooter class=\"slot-footer\"\u003e\u003c/footer\u003e\n  \u003c/div\u003e\n*/\nconst LayoutDefault = props =\u003e {\n  const { children } = props\n  return (\n    \u003cLayout className='layout-default'\u003e\n      \u003cSlot name='header' as='header' content={children}\u003eWelcome!\u003c/Slot\u003e\n      \u003cSlot className='main' role='main' content={children} /\u003e\n      \u003cSlot name='info' content={children}\u003eCopyright 2017\u003c/Slot\u003e\n      \u003cSlot name='footer' as='footer' content={children} /\u003e\n    \u003c/Layout\u003e\n  )\n}\n```\n\nTo insert content into a `Slot` the parent component using the layout needs to\ndesignate React subtrees to use a slot by setting the `slot` prop on an element\nto have its children inserted into the slot with the mathcing name (if one\nexists). *Only the first matching React subtree will have its children inserted.*\n\n```jsx\n\u003cdiv slot='slot-name'\u003e...inserted into the slot-name slot...\u003c/div\u003e\n```\n\nAny React elements with a `slot` set to `\"default\"`, or `true` will have thier\nchildren inserted into the default slot (if one exists).\n\n```jsx\n\u003cdiv slot\u003e...inserted into the default slot...\u003c/div\u003e\n\u003cdiv slot='default'\u003e...inserted into the default slot...\u003c/div\u003e\n```\n\nSince only the children of a react subtree are inserted into a slot, all props\non the subtree root node are merged with the props defined on the `\u003cSlot\u003e`\nelement in the layout.\n\n```jsx\n// in the layout...\n\u003cSlot name='footer' className='footer' /\u003e\n\n// in the parent component...\n\u003cLayout\u003e\n  \u003cdiv slot='footer' className='my-footer'\u003eThe Footer\u003c/div\u003e\n\u003c/Layout\u003e\n\n// Results in the footer slot being rendered as...\n\u003cdiv class=\"slot-footer footer my-footer\"\u003eTheFooter\u003c/div\u003e\n```\n\nAlso, if a default slot exists and no slotted subtree is found with the `slot`\nprop set to `\"default\"` or `true`, then all React nodes without a slot\ndesignation will be inserted into the default slot.\n\n```jsx\n\u003cdiv slot='slot-name'\u003e...\u003c/div\u003e\n\u003cdiv\u003eDefault content1\u003c/div\u003e\n\u003cdiv\u003eMore default content\u003c/div\u003e\n\u003cdiv slot='slot-name2'\u003e...\u003c/div\u003e\n```\n\nExample Usage of `LayoutDefault`:\n\n```jsx\n/*\n  A page component that uses LayoutDefault to structure its content. This\n  will render a page that looks like this:\n\n  \u003cdiv class=\"layout-default\"\u003e\n    \u003cheader\u003eWelcome!\u003c/header\u003e\n    \u003cdiv class=\"slot-default main\" role=\"main\"\u003e\n      \u003cdiv\u003eHello World!\u003c/div\u003e\n      \u003cp\u003eThis is some more content inserted into the default slot\u003c/p\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"slot-info\"\u003eCopyright 2018\u003c/div\u003e\n  \u003c/div\u003e\n*/\nconst Page = props =\u003e {\n  return (\n    \u003cLayoutDefault\u003e\n      \u003cdiv slot='info'\u003eCopyright 2018\u003c/div\u003e\n      \u003cdiv\u003eHello World!\u003c/div\u003e\n      \u003cp\u003eThis is some more content inserted into the default slot\u003c/p\u003e\n    \u003c/LayoutDefault\u003e\n  )\n}\n```\n\nAdditionally, Slots can be nested to provide parent components with increasing\ngranularity when overriding slots.\n\n```jsx\n\u003cSlot name='outer' content={children}\u003e\n  This is the content\n  \u003cSlot name='inner' content={children}\u003e\n    This is the inner content\n  \u003c/Slot\u003e\n\u003c/Slot\u003e\n```\n\nThen to insert into these slots you have a choice to override the entire `outer`\nslot...\n\n```jsx\n\u003cdiv slot='outer'\u003e...\u003c/div\u003e\n```\n\n...or just the `inner` slot.\n\n```jsx\n\u003cdiv slot='inner'\u003e....\u003c/div\u003e\n```\n\nBut if the `outer` slot is overrdden then the entirety of its contents will be\nreplaced.\n\n### slot(name, children)\n\nThis function will pull out the children of any React subtree designated by the\n`slot` prop that matches the `name` argument. This function will not render a\nroot node at all, this is left up to the parent component to provide. This gives\nyou more control over a slot's root element.\n\n```jsx\n\u003cSlot name='footer' content={children}\u003e\n  Copyright {slot('copyrightYear', children) || '2017'}\n\u003c/Slot\u003e\n```\n\nThen in the parent component:\n\n```jsx\n// Replace the entire footer...\n\u003cdiv slot='footer'\u003e...\u003c/div\u003e\n\n// ...or just replace the copyright year\n\u003cdiv slot='copyrightYear'\u003e2018\u003c/div\u003e\n```\n\n## Related Modules\n\n- [react-layout](https://npmjs.org/react-layout)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdschnare%2Freact-slot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdschnare%2Freact-slot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdschnare%2Freact-slot/lists"}