{"id":42830288,"url":"https://github.com/wide/modulus","last_synced_at":"2026-01-30T11:26:46.258Z","repository":{"id":43694163,"uuid":"267885261","full_name":"wide/modulus","owner":"wide","description":"Robust Web Component interface.","archived":false,"fork":false,"pushed_at":"2022-07-08T17:09:31.000Z","size":32,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-09-28T09:54:16.061Z","etag":null,"topics":["modulus"],"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/wide.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":"2020-05-29T14:59:09.000Z","updated_at":"2025-04-02T09:12:35.000Z","dependencies_parsed_at":"2022-09-10T11:50:54.209Z","dependency_job_id":null,"html_url":"https://github.com/wide/modulus","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/wide/modulus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wide%2Fmodulus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wide%2Fmodulus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wide%2Fmodulus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wide%2Fmodulus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wide","download_url":"https://codeload.github.com/wide/modulus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wide%2Fmodulus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28911821,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T08:15:08.179Z","status":"ssl_error","status_checked_at":"2026-01-30T08:14:31.507Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["modulus"],"created_at":"2026-01-30T11:26:45.775Z","updated_at":"2026-01-30T11:26:46.250Z","avatar_url":"https://github.com/wide.png","language":"JavaScript","readme":"# Modulus\r\n\r\nRobust Web Component interface, based on `@wide/dom-observer`.\r\n\r\n\r\n## Install\r\n\r\n```\r\nnpm install @wide/modulus --save\r\n```\r\n\r\n\r\n## Usage\r\n\r\n\r\n### Register a regular component\r\n\r\n```js\r\nimport modulus from '@wide/modulus'\r\n\r\nmodulus.component('foo-bar', class {\r\n  run() {\r\n\r\n  }\r\n})\r\n\r\n// or batch\r\nmodulus.components({\r\n  'foo-bar': class {\r\n    run() {\r\n\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n```html\r\n\u003cbody\u003e\r\n  \u003cdiv is=\"foo-bar\"\u003eHey!\u003c/div\u003e\r\n\u003c/body\u003e\r\n```\r\n\r\n### Register a web component\r\n\r\nThe name given to the component must contains a `-` to comply to the custom-element naming convention.\r\n\r\n```js\r\nimport modulus from '@wide/modulus'\r\n\r\nmodulus.webComponent('foo-bar', class {\r\n  run() {\r\n\r\n  }\r\n})\r\n\r\n// or batch\r\nmodulus.webComponents({\r\n  'foo-bar': class {\r\n    run() {\r\n\r\n    }\r\n  }\r\n})\r\n```\r\n\r\n```html\r\n\u003cbody\u003e\r\n  \u003cfoo-bar\u003eHey!\u003c/foo-bar\u003e\r\n\u003c/body\u003e\r\n```\r\n\r\n### Get all components by name and selector\r\n\r\n```js\r\nimport modulus from '@wide/modulus'\r\n\r\nmodulus.seekAll('foo-bar') // Array\u003cFooBar\u003e\r\nmodulus.seekAll('foo-bar', '.visible') // Array\u003cFooBar.visible\u003e\r\n```\r\n\r\n### Get one component by name and selector\r\n\r\n```js\r\nimport modulus from '@wide/modulus'\r\n\r\nmodulus.seek('foo-bar') // first FooBar instance\r\nmodulus.seek('foo-bar', '#foobar1') // FooBar#foobar1 instance\r\n```\r\n\r\n### Get component(s) from external source\r\n\r\n```js\r\ndocument.queryComponent('foo-bar') // first FooBar instance\r\ndocument.queryComponents('foo-bar', '.visible') // Array\u003cFooBar.visible\u003e\r\n```\r\n \r\n### Call component's method from `html`\r\n\r\nUse the `[data-call]` helper with a formatted value `name#id.method`:\r\n```html\r\n\u003cbutton data-call=\"modal#register.open\"\u003edo something\u003c/button\u003e\r\n```\r\n\r\nwill internally trigger:\r\n```js\r\nmodulus.seek('modal', '#register').open({ el, e, data })\r\n```\r\n\r\n| Value | Description |\r\n|---|---|\r\n| `el` | HTMLElement object binded to the event |\r\n| `e` | `Event` object of the event listener method callback |\r\n| `data` | Optional parameters defined in `[data-call.params]` |\r\n\r\n#### Parameters\r\nUse the `[data-call.params]` to pass custom values:\r\n\r\n```html\r\n\u003cbutton data-call=\"modal#register.open\" data-call.params='[{ \"myAttr\": \"myValue\" }]'\u003edo something\u003c/button\u003e\r\n```\r\n\r\n\u003e ⚠️ Note: `data-call.params` is waiting a JSON format only\r\n\r\nExmple with the previous HTML code:\r\n```js\r\nmodulus.component('modal', class extends Component {\r\n  run() {\r\n    // ...\r\n  }\r\n\r\n  /**\r\n   * Open modal and do some stuff\r\n   *\r\n   * @params {HTMLElement} el\r\n   * @params {Event} e\r\n   * @params {Object|null} [data]\r\n   */\r\n  open({ el, e, data }) {\r\n    // el: \u003cbutton ...\u003e\r\n    // e: Event{ ... }\r\n    // data: { ... } | null\r\n  }\r\n```\r\n\r\n**Deprecated method:** To ensure compatibility with the old `$event` and `$el` parameters (used by Modulus below v2.2.0), it still possible to use them. For this, consult the [old documentation](https://github.com/wide/modulus/tree/2.1.2#parameters). \r\n\r\n\u003e ⚠️ Note: Keep in mind that this method should not be used with new projects. It can be removed at any time on the next release. \r\n\r\n## Component class\r\n\r\nThe `Component` class offers shortcuts for accessing element or sending events to other components.\r\n\r\n```js\r\nimport modulus from '@wide/modulus'\r\nimport Component from '@wide/modulus/src/component'\r\n\r\nmodulus.component('foo-bar', class extends Component {\r\n  run() {\r\n    this.log(`I'm in the DOM !`)\r\n  },\r\n  destroy() {\r\n    this.log(`I'm no longer in the DOM...`)\r\n  }\r\n})\r\n```\r\n\r\n### Properties\r\n\r\n- `el` the DOM element binded to the class\r\n- `uid` unique ID given at the registration\r\n- `attrs` element's attributes\r\n- `dataset` element's data-attributes\r\n- `refs` element's specific children (fetched using `[ref]` and `[ref.dyn]` attributes)\r\n  - `[ref]` elements are computed on component initial load\r\n  - `[ref.dyn]` elements are computed on each access\r\n  - `[ref.group]` elements are grouped in an array under the same key (`[ref=bar]` -\u003e `this.refs.bar[0]`)\r\n\r\n### Hooks\r\n\r\n- `run()` hook called when the element is inserted in DOM\r\n- `destroy()` hook called when the element is removed from DOM\r\n\r\n### Methods\r\n\r\n- `child(selector)` alias of `this.el.querySelector()`, return `HTMLElement`\r\n- `children(selector)` alias of `this.el.querySelectorAll()`, return `NodeList`\r\n- `on(event, callback)` listen global event\r\n- `emit(event, callback)` trigger global event\r\n- `off(event, callback)` remove global listener\r\n- `log(...args)` log message with unique identifier\r\n- `log.info(...args)` log message with INFO severity\r\n- `log.warn(...args)` log message with WARN severity\r\n- `log.error(...args)` log message with ERROR severity\r\n\r\n### Garbage Collector\r\n\r\nEvery event listeners created using `this.on()` are automatically `off()`ed on component destruction.\r\n\r\n\r\n## Config\r\n\r\n### Log level\r\n\r\nTo keep only `warn` and `error` logs (for production usage), set `production` to `true`:\r\n```js\r\nimport modulus from '@wide/modulus'\r\n\r\nmodulus.config({ production: true })\r\n```\r\n\r\nOr manually assign a log level:\r\n```js\r\nimport modulus, { LOG_LEVELS } from '@wide/modulus'\r\n\r\nmodulus.config({\r\n  log: {\r\n    level: LOG_LEVELS.INFO // DEBUG (default), INFO, WARN, ERROR, NONE\r\n  }\r\n})\r\n```\r\n\r\n\u003e ⚠️ Note: assign a log level will override the `production` setting.\r\n\r\nTo disable logs, set `enabled` to `false`:\r\n```js\r\nimport modulus from '@wide/modulus'\r\n\r\nmodulus.config({\r\n  log: {\r\n    enabled: false\r\n  }\r\n})\r\n```\r\n\r\nThe default config is setted to show all kind of logs.\r\n\r\n\r\n## Authors\r\n\r\n- **Aymeric Assier** - [github.com/myeti](https://github.com/myeti)\r\n- **Julien Martins Da Costa** - [github.com/jdacosta](https://github.com/jdacosta)\r\n\r\n### Contributors\r\n\r\n- **Sébastien Robillard** - [github.com/robiseb](https://github.com/robiseb)\r\n- **Kévin Poccard Soudard** - [github.com/kevpoccs](https://github.com/kevpoccs)\r\n\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the [licence](licence) file for details","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwide%2Fmodulus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwide%2Fmodulus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwide%2Fmodulus/lists"}