{"id":19441526,"url":"https://github.com/dgca/react-polly","last_synced_at":"2025-04-25T00:30:56.126Z","repository":{"id":43919907,"uuid":"511777746","full_name":"dgca/react-polly","owner":"dgca","description":"🛠 A polymorphic component factory for React ⚛️","archived":false,"fork":false,"pushed_at":"2022-07-08T14:22:25.000Z","size":133,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-14T10:31:46.496Z","etag":null,"topics":["react","react-native","reactjs"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/dgca.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":"2022-07-08T05:48:00.000Z","updated_at":"2023-10-20T09:06:20.000Z","dependencies_parsed_at":"2022-09-12T07:10:43.372Z","dependency_job_id":null,"html_url":"https://github.com/dgca/react-polly","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgca%2Freact-polly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgca%2Freact-polly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgca%2Freact-polly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgca%2Freact-polly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dgca","download_url":"https://codeload.github.com/dgca/react-polly/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223973590,"owners_count":17234485,"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":["react","react-native","reactjs"],"created_at":"2024-11-10T15:35:57.839Z","updated_at":"2024-11-10T15:35:58.507Z","avatar_url":"https://github.com/dgca.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `react-polly`\n\n 🛠 **polymorphic** _component factory_ for React ⚛️\n\n**[Bootstrapped with `dts-cli`](https://github.com/weiran-zsd/dts-cli)**\n\n## Status\n\n[![stability-experimental](https://img.shields.io/badge/stability-experimental-orange.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#experimental)\n\nThis library is pre-release, as I'm still trying to work out the best API for this. Feedback is very apprecaited! If you have any ideas, please submit an issue or open a PR 🙏\n\n## What it does:\n\n`react-polly` provides a quick and easy way to create polymorphic components—that is, components that can return different underlying elements based on an `as` prop passed in by the caller.\n\nAdditionally, it handles ref forwarding via `React.forwardRef`, and it manages merging additional prop types based on the provided `as` prop.\n\n## How to use it:\n\n_Note: This assumes you're using TypeScript._\n\n**Install:** `npm install react-polly` or `yarn add react-poly`\n\n`polly` is a generic function that takes two type arguments and one regular function argument.\n\nThe type arguments specify the default element type your component will return, and the prop types that your component will handle.\n\nThe main function argument is your component definition.\n\nNote that although you must use the same default element type as the first type argument, and as the default value for your `as` prop.\n\n```tsx\nimport polly from 'react-polly';\n\ntype TextProps = {\n  color?: \"black\" | \"red\" | \"blue\";\n  children: React.ReactNode;\n};\n\n// Here we create a polymorphic \u003cText\u003e component that returns a \u003cspan\u003e by default.\nconst Text = polly\u003c\"span\", TextProps\u003e(function Text(\n  {\n    // You must provide the same default value for the `as` prop as you\n    // passed to the first generic type argument.\n    // You must also rename the `as` prop to an Uppercase word cause React\n    // component names must be capitalied.\n    as: Component = \"span\",\n    color = \"black\",\n    children,\n    ...rest\n  },\n  ref?\n) {\n  return (\n    \u003cComponent\n      {...rest}\n      ref={ref}\n      style={{\n        color\n      }}\n    \u003e\n      {children}\n    \u003c/Component\u003e\n  );\n});\n\ntype YellerProps = {\n  children: React.ReactNode;\n  exclamationCount: number;\n};\n\n// This is a regular component for demo purposes below.\nfunction Yeller({ children, exclamationCount, ...rest }: YellerProps) {\n  return (\n    \u003cspan {...rest}\u003e\n      {children}\n      {Array.from({ length: exclamationCount })\n        .map(() =\u003e \"!\")\n        .join(\"\")}\n    \u003c/span\u003e\n  );\n}\n\nfunction Demo() {\n  return (\n    \u003cdiv className=\"app\"\u003e\n      \u003ch1\u003ereact-polly\u003c/h1\u003e\n      {/* This will render a \u003cspan\u003e element */}\n      \u003cText\u003eHello! I'm a polymorphic element.\u003c/Text\u003e\n      \u003cbr /\u003e\n      {/* This will render a \u003cstrong\u003e tag */}\n      \u003cText color=\"red\" as=\"strong\"\u003e\n        I can render any type of element that you specify via my `as` prop.\n      \u003c/Text\u003e\n      \u003cbr /\u003e\n      {/* This will render a Yeller component */}\n      \u003cText as={Yeller} exclamationCount={10} color=\"blue\"\u003e\n        I can even render as other React Components\n      \u003c/Text\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n## Appendix\n\n* Shoutout to Ben Ilegbodu for [this blog post](https://www.benmvp.com/blog/forwarding-refs-polymorphic-react-component-typescript/) which was super useful when writing this library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgca%2Freact-polly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdgca%2Freact-polly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgca%2Freact-polly/lists"}