{"id":13793500,"url":"https://github.com/zaceno/hyperapp-context","last_synced_at":"2025-05-12T20:31:03.249Z","repository":{"id":90087715,"uuid":"121651927","full_name":"zaceno/hyperapp-context","owner":"zaceno","description":"Context-aware components in Hyperapp","archived":true,"fork":false,"pushed_at":"2020-03-11T22:33:57.000Z","size":94,"stargazers_count":16,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-24T17:06:22.168Z","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.md","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":"2018-02-15T16:24:06.000Z","updated_at":"2023-01-28T15:28:19.000Z","dependencies_parsed_at":"2023-03-02T23:00:14.389Z","dependency_job_id":null,"html_url":"https://github.com/zaceno/hyperapp-context","commit_stats":{"total_commits":44,"total_committers":3,"mean_commits":"14.666666666666666","dds":"0.20454545454545459","last_synced_commit":"5e252648564c70b09bb7e964a919ee38db5766e8"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaceno%2Fhyperapp-context","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaceno%2Fhyperapp-context/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaceno%2Fhyperapp-context/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaceno%2Fhyperapp-context/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zaceno","download_url":"https://codeload.github.com/zaceno/hyperapp-context/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253816692,"owners_count":21968867,"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.523Z","updated_at":"2025-05-12T20:31:02.744Z","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# \u003cimg height=24 src=https://cdn.rawgit.com/JorgeBucaran/f53d2c00bafcf36e84ffd862f0dc2950/raw/882f20c970ff7d61aa04d44b92fc3530fa758bc0/Hyperapp.svg\u003e hyperapp-context \n\n[![Travis CI](https://api.travis-ci.org/zaceno/hyperapp-context.svg?branch=master)](https://travis-ci.org/zaceno/hyperapp-context) [![npm](https://img.shields.io/npm/v/hyperapp-context.svg)](https://www.npmjs.org/package/hyperapp-context)\n\nIn [Hyperapp](https://hyperapp.js.org), the way to provide data to components is by passing properties to them. If your component tree is deep, and finely separated, this can quickly become repetetitive and burdensome -- and may lead to hard-to-find bugs.\n\n\"Contexts\" offer a *complementary* (not exclusive) way of providing data to components which can remedy the situation.\n\nThis \"higher-order-app\" (or app decorator) enables the use of context in Hyperapp-apps.\n\n## Installation\n\nIf you're using a module bundler, install With npm or Yarn:\n\n\u003cpre\u003e\nnpm i \u003ca href=https://www.npmjs.com/package/hyperapp-context\u003ehyperapp-context\u003c/a\u003e\n\u003c/pre\u003e\n\nAnd then import the same way you would anything else, in the same file where you import `app` from Hyperapp\n\n```js\nimport {h, app as _app} from \"hyperapp\"\nimport context from \"hyperapp-context\"\n```\n\nAlternatively, if you're not using a module bunder, you can download hyperapp-context from a CDN like [unpkg.com](https://unpkg.com/hyperapp-context) and it will be globally available as \u003csamp\u003ewindow.context\u003c/samp\u003e.\n\n```html\n\u003c!doctype html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cmeta charset=\"utf-8\"\u003e\n  \u003cscript src=\"https://unpkg.com/hyperapp\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://unpkg.com/hyperapp-context\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n\u003c/html\u003e\n```\n\n## Usage\n\n### Enable context\n\nIn order to enable the context system in your app, don't call Hyperapp's `app` directly. First, wrap it with `withContext`.\n\n```js\nimport {app as _app} from 'hyperapp'\nimport {withContext} from 'hyperapp-context'\nconst app = withContext(_app)\n\n//...\n\napp(state, actions, view, container)\n```\n\n### Access context in components\n\nThe \"context\" is a set of data available to components without the need to pass it as props from its parent-container. In order to access context-data, define your components using this signature:\n\n```jsx\nconst MyComponent = (props, children) =\u003e context =\u003e (\n    \u003cdiv class={context.foo}\u003e{context.bar}\u003c/\u003e\n)\n```\n\n### Write to the context\n\nIn order for a component to have access to data in the context, it must first have been written to the context, by a component higher up in the component-tree. A component can write to the context using the function provided as the second argument after the `context`.\n\n```jsx\nconst GrandDadComponent = (props, children) =\u003e (context, setContext) =\u003e {\n    setContext({\n        foo: 'foo',\n        bar: 'bar',\n    })\n    return (\n        \u003cdiv\u003e\n        ...\n        \u003c/div\u003e\n    )\n}\n```\n\nThe example makes `foo` and `bar` available to any decendant in the component tree.\n\nIf any components even further up the tree had already defined `foo` or `bar`, this would override those values for any decendants of `GrandDadComponent`, but *siblings* would recieve the original valuues.\n\n#### Define context directly in the view\n\nYou can write to the context for your entire app, by setting it in your view. A common use for this is to make `state` and `actions` available to all components.\n\n```js\n\nconst view = (state, actions) =\u003e (context, setContext) =\u003e {\n    setContext({state, actions})\n    return (\n        \u003cmain\u003e\n            ...\n        \u003c/main\u003e\n    )\n}\n\n```\n\n#### Use a component to set context\n\nA technical limitation with the `setContext` function described above, is that it should really only be called once in a component. If called multiple times, only the last call will have an effect.\n\nIf you would like to apply different contexts to different branches of descendants in a component, first define a component that can be used to set the context:\n\n```js\nconst SetContext = (props, children) =\u003e (_, setContext) =\u003e {\n  setContext(props)\n  return children\n}\n\n```\n\nNow you may use this to define different contexts for different branches inside a single component/view:\n\n```jsx\nconst view = (state, actions) =\u003e (\n  \u003cSetContext state={state} actions={foo}\u003e\n    \u003cmain\u003e\n      \u003csection class=\"toolbar\"\u003e\n        \u003cSetContext section=\"toolbar\"\u003e\n          \u003cFooButton /\u003e\n          \u003cBarButton /\u003e\n        \u003c/SetContext\u003e\n      \u003c/section\u003e\n      \u003csection class=\"main\"\u003e\n        \u003cSetContext section=\"main\"\u003e\n          \u003cMain /\u003e\n        \u003c/SetContext\u003e\n      \u003c/section\u003e\n    \u003c/main\u003e\n  \u003c/SetContext\u003e\n)\n```\n\n\n### Example\n\nThis [TodoMVC example](https://codepen.io/zaceno/pen/gvGgQP?editors=0010) makes liberal (extreme, perhaps...) use of context.\n\n## Nestable\n\nEmbed hyperapp-apps in your main app, as if they were components. \n\nUsage is exactly as in https://github.com/zaceno/hyperapp-nestable, except for these two details:\n\nImport using:\n\n```js\nimport {nestable} from 'hyperapp-context'\n```\n\nThese nestables are *context enabled*, meaning you get access to the external context in the nestable's view, and can share data from the component with its children, via context:\n\n```js\nconst MyComponent = nestable(\n  //State\n  {...},\n\n  //Actions\n  {...},\n\n  //View\n  (state, actions) =\u003e (props, children) =\u003e (context, setContext) =\u003e {\n    setContext({...})\n    return children\n  }\n)\n```\n\n## Preprocessing the VDOM\n\nSometimes you want a component which does not itself add anything to the virtual-dom-tree, but simply modifies it's children in some way, for example, by attaching dom handlers. For this purpose, we export `processor`\n\n```jsx\nimport {processor} from 'hyperapp-context'\n\nconst MyProcessor = processor((props, children, context) =\u003e {\n  /*\n    Here, props will be {foo: 'bar'}\n    children will be {nodeName: 'p', attributes: {}, children: ['bop']}\n    return whatever you want to make of this.\n  */\n})\n\nconst Child = _ =\u003e context =\u003e \u003cp\u003ebop\u003c/p\u003e\n\n...\n\u003cMyProcessor foo=\"bar\"\u003e\u003cChild\u003e\u003c/MyProcessor\u003e\n...\n\n```\n\n### Decorators\n\nWorking directly with vnodes as in the example above is rarely necessary, and a bit rough. Most often what you\nwant to do is simply to add a few event/lifecycle handers or perhaps a class to the child nodes. To facilitate\nthis we export `decorator` which lets you define a processing component that does just that:\n\n```jsx\nconst SelectionDecorator = decorator(({row, col}, {selection}) =\u003e ({\n    onmousedown: ev =\u003e {\n        ev.preventDefault(true)\n        selection.start({row, col})\n    },\n    onmouseup: ev =\u003e {\n        ev.preventDefault(true)\n        selection.end({row, col})\n    },\n    onmouseover: ev =\u003e {\n        ev.preventDefault(true)\n        selection.select({row, col})\n    },\n    class: selection.isSelected({row, col}) \u0026\u0026 'selected'\n}))\n\n//...\n\n\u003cSelectionDecorator row={i} col={j}\u003e\n\u003ctd\u003e{values[i][j]}\u003c/td\u003e  \n\u003c/SelectionDecorator\u003e\n\n//...\n```\n\n## Example\n\nThis example demonstrates using a nestable as a provider of selection state and actions via the context, and decorating table cells with selection event handlers, so that you can operate on the main state using the selection\ndata.\n\nhttps://codepen.io/zaceno/pen/vdwQdy?editors=0110\n\n## License\n\nhyperapp-context is MIT licensed. See [LICENSE.md](./LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaceno%2Fhyperapp-context","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzaceno%2Fhyperapp-context","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaceno%2Fhyperapp-context/lists"}