{"id":22220522,"url":"https://github.com/drawbotics/fnfy","last_synced_at":"2025-03-25T07:41:28.675Z","repository":{"id":35004410,"uuid":"180966326","full_name":"Drawbotics/fnfy","owner":"Drawbotics","description":"A small collection of utilities to be able to work without JSX","archived":false,"fork":false,"pushed_at":"2023-01-04T03:51:45.000Z","size":850,"stargazers_count":1,"open_issues_count":13,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-09T04:04:45.854Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Drawbotics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-12T08:36:31.000Z","updated_at":"2019-07-07T16:04:44.000Z","dependencies_parsed_at":"2023-01-15T11:51:01.971Z","dependency_job_id":null,"html_url":"https://github.com/Drawbotics/fnfy","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/Drawbotics%2Ffnfy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drawbotics%2Ffnfy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drawbotics%2Ffnfy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drawbotics%2Ffnfy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Drawbotics","download_url":"https://codeload.github.com/Drawbotics/fnfy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245422921,"owners_count":20612725,"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-12-02T23:08:57.398Z","updated_at":"2025-03-25T07:41:28.653Z","avatar_url":"https://github.com/Drawbotics.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FNFY\n\nA small set of tools to ease the usage of React without JSX.\n\n\n## Example\n\n```javascript\nimport fnfy, { View } from 'fnfy';\nimport _ThirdPartyComponent from 'third-party-component';\nimport PropTypes from 'prop-types';\n\n\nconst ThirdPartyComponent = fnfy(_ThirdPartyComponent);\nconst Img = fnfy('img');\n\n\nconst MyComponent = ({ images }) =\u003e {\n  return View({\n    className: 'MyComponent',\n    children: ThirdPartyComponent({\n      someProps: 'someValue',\n      children: [\n        Img({ src: images.b }),\n        Img({ src: images.a }),\n      ],\n    }),\n  });\n};\n\n\nMyComponent.propTypes = {\n  images: PropTypes.object.isRequired,\n};\n\n\nexport default fnfy(MyComponent);\n```\n\n\n## API\n\n### `fnfy(Component)`\n\nBase funtionality, wraps the component so it can be used as a function no matter what the original component was (a class or a function). It also adds some important stuff like the ability to use `instances` (more to it later) and make sure we always use `createElement` at the end.\n\nIt can be used to wrap own components, external components or string components.\n\n### `View(props)`\n\nReplace `div` component with `View` component to have a base component and not having to wrap all the time `div` in `fnfy('div')`. Also, forward refs by default so it behaves like a normal base component.\n\nIt accepts all the props a React component would, so we can have a 1:1 equivalence between both.\n\n### `cloneElement(Component, newProps)`\n\nWrapper around `React.cloneElement` to make sure everything gets cloned the right way.\n\n### `useInstance()`\n\nSo before, instances were mentioned, what are they? Well, since the idea with hooks is that every React component is now a function based component, it's not possible to expose methods from the children to the parent anymore. This aims to fix this issue. The way of using it it's the following:\n\n```javascript\nimport { useState } from 'react';\nimport fnfy, { View, useInstance } from 'fnfy';\n\n\nconst Button = fnfy('button');\n\n\n// Every fnfy-ied component gets a prop called `inst` that can be\n// used to pass methods to the parent or anyone attached to the inst\nconst MyChild = fnfy(({ inst }) =\u003e {\n  const [ stuff, setStuff ] = useState(false);\n\n  inst.setInstance(() =\u003e ({\n    toggleStuff: () =\u003e {\n      setStuff( ! stuff);\n    },\n  }));\n\n  return View({\n    className: stuff ? 'OneStuff' : 'OtherStuff',\n  });\n});\n\n\nconst MyParent = () =\u003e {\n  const childInst = useInstance();\n  return View({\n    className: 'Parent',\n    children: [\n      MyChild({ inst: childInst }),\n      Button({\n        children: 'Click Here',\n        onClick: () =\u003e childInst.toggleStuff(),\n      }),\n    ],\n  });\n};\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrawbotics%2Ffnfy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrawbotics%2Ffnfy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrawbotics%2Ffnfy/lists"}