{"id":13793503,"url":"https://github.com/zaceno/hyperapp-nestable","last_synced_at":"2025-05-12T20:31:04.390Z","repository":{"id":71592063,"uuid":"101386773","full_name":"zaceno/hyperapp-nestable","owner":"zaceno","description":"Embed apps in other apps, as if they were components","archived":true,"fork":false,"pushed_at":"2020-03-11T22:33:06.000Z","size":41,"stargazers_count":40,"open_issues_count":1,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-14T12:55:30.289Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/zaceno.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-25T09:06:34.000Z","updated_at":"2024-03-14T07:13:04.000Z","dependencies_parsed_at":"2023-03-02T23:00:13.222Z","dependency_job_id":null,"html_url":"https://github.com/zaceno/hyperapp-nestable","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/zaceno%2Fhyperapp-nestable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaceno%2Fhyperapp-nestable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaceno%2Fhyperapp-nestable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaceno%2Fhyperapp-nestable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zaceno","download_url":"https://codeload.github.com/zaceno/hyperapp-nestable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253816693,"owners_count":21968868,"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-03T23:00:22.617Z","updated_at":"2025-05-12T20:31:03.949Z","avatar_url":"https://github.com/zaceno.png","language":"JavaScript","funding_links":[],"categories":["Utilities V1"],"sub_categories":[],"readme":"This project is only compatible with hyperapp v1, and I do not intend to maintain it any longer. Hence, I am archiving it.\n\n# hyperapp-nestable\n\nA tiny wrapper around your app, that lets you embed it within other hyperapp apps, *as if it were a component*. Effectively answering the age-old question: \"How do I make components with local state, like React's Object components, in Hyperapp?\"\n\n## Install\n\n### ...using npm\n\n```\nnpm install hyperapp-nestable\n```\n\nAnd `require` (or `import`, if you're using es6 modules) in your project:\n\n```js\n\nconst nestable = require('hyperapp-nestable')\n\n```\n\n### ... or include in HTML from CDN\n\nAdd this to the `\u003chead\u003e` of your page:\n\n```html\n\n\u003cscript src=\"https://unpkg.com/hyperapp-nestable\"\u003e\u003c/script\u003e\n\n```\n\nthis will export `nestable` in the global scope.\n\n## Basic Usage\n\nUse the `nestable` function in the following way:\n\n```\nvar ComponentName = nestable(initialState, actions, view)\n```\n\n... which is to say, just like you start a normal Hyperapp-app. The difference is, you don't provide a container. That is becuase instead of attaching an app to the dom immediately, `nestable` returns a component-function which will start a hyperapp app, attached to the DOM, when and where the component is rendered.\n\nAn example:\n\n```jsx\n\n/*\n  Define a stateful Counter component\n*/\nconst Counter = nestable(\n  //STATE\n  {value: 0},\n  \n  //ACTIONS\n  {\n    up: _ =\u003e state =\u003e ({value: state.value + 1}),\n    down: _ =\u003e state =\u003e ({value: state.value - 1}),\n  },\n  \n  //VIEW\n  (state, actions) =\u003e (\n    \u003cp\u003e\n      \u003cbutton onclick={actions.down}\u003e-\u003c/button\u003e\n      {state.value}\n      \u003cbutton onclick={actions.up}\u003e+\u003c/button\u003e\n    \u003c/p\u003e\n  )\n)\n\n\n/*\n  Use the Counter-component in an app\n*/\n\napp({}, {}, _ =\u003e (\n  \u003cdiv class=\"app\"\u003e\n    \u003ch1\u003eLook, a counter:\u003c/h1\u003e\n    \u003cCounter /\u003e\n  \u003c/div\u003e\n), document.body)\n\n```\n\n([Live example](https://codepen.io/zaceno/pen/eygwdV))\n\nThe above example will do exactly what you expect, and render a functioning counter after the heading.\n\n## Component's Tagname\n\nIf you look at the html of the app example above, you'll see it looks like:\n\n```html\n\u003cdiv class=\"app\"\u003e\n  \u003ch1\u003eLook, a counter:\u003c/h1\u003e\n  \u003cx-\u003e\n    \u003cp class=\"counter\"\u003e\n      \u003cbutton\u003e-\u003c/button\u003e\n      0\n      \u003cbutton\u003e+\u003c/button\u003e\n    \u003c/p\u003e\n  \u003c/x-\u003e\n\u003c/div\u003e\n```\n\nNotice the `\u003cx-\u003e` element in there. That element corresponds to the vnode in the main app's view, where the counter's view is rendered. It's necessary as a means to \"connect\" the two vtrees. But the tag name `x-` is just the default. If you want it to be something more descriptive, we might call it `counter-` (the dash on the end is just to make it clear it's not a real html element). You would do that by giving it as the fourth argument to the `nestable` function:\n\n```js\nconst Counter = nestable(\n  initialCounterState,\n  counterActions,\n  counterView,\n  'counter-'\n)\n```\n\nYou could make the tag a regular html tag such as `div` or `section` too. You may want that for CSS-reasons.\n\n\n## Component properties \u0026 children\n\nYou can pass props and children to a component (just like any other). In order for your view to be aware of them, return a component from your view.\n\n```jsx\nconst MyComponent = nestable(\n  //STATE\n  {...},\n\n  //ACTIONS\n  {...},\n\n  //VIEW\n  (state, actions) =\u003e (props, children) =\u003e (\n    \u003cdiv class={props.class}\u003e\n      \u003ch1\u003e{state.foo}\u003c/h1\u003e\n      {children}\n      \u003cbutton onclick={actions.bar}\u003eGo\u003c/button\u003e\n    \u003c/\n  )\n)\n\n```\n\n### Special properties\n\n#### `key`\n\nThey key property is set on the component's tag (not the top node of the component's `view`). This can be very important when you have components as siblings to eachother in the virtual dom.\n\n#### `class` \u0026 `id`\n\nThese are set on the component's tag. Mainly useful for css purposes. \n\n#### `oncreate`, `onupdate`, `ondestroy`\n\nThese lifecycle events are first use for managing the component, but afterward, will be called just as usual, for the component's node.\n\n## Nestable component lifecycle\n\n### The special action called `init`\n\nIf you add an action called `init` to your component, this action will be called when the component is first rendered. It will be passed the component's props as its first argument.\n\nSuch as if you want your `Counter` component to accept a starting value as a prop, you don't want the actual value to change when whatever was the basis for the starting value changes. So you could implement the counter this way:\n\n```js\n\nconst Counter = nestable(\n  \n  //INITIAL STATE\n  { value: 0 },\n  \n  //ACTIONS\n  {\n    init: props =\u003e ({value: props.initial || 0}),\n    up: _ =\u003e state =\u003e ({value: state.value + 1}),\n    down: _ =\u003e state =\u003e ({value: state.value - 1}),\n  },\n  \n  //VIEW\n  ...\n)\n```\n\nNow, the counter will start at the value it is given the first time it's rendered, but when that value changes, it will not affect the value of the counter.\n\nHere's a [live example](https://codepen.io/zaceno/pen/ypMLPp)\n\n### The special action called `uninit`\n\nCorresponding to `init`, if you need something done when the component is destroyed, you can put in an action named `uninit`\n\nHere is a more complex, while  somewhat contrived demonstrating many of the features mentioned here.\n\nhttps://codepen.io/zaceno/pen/bajpvO?editors=0011\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaceno%2Fhyperapp-nestable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzaceno%2Fhyperapp-nestable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaceno%2Fhyperapp-nestable/lists"}