{"id":16433926,"url":"https://github.com/gund/ngx-element-boundary","last_synced_at":"2026-04-17T13:32:39.582Z","repository":{"id":38174306,"uuid":"277945870","full_name":"gund/ngx-element-boundary","owner":"gund","description":"Strategy for @angular/elements that allows to inherit Injectors between any Angular Custom Elements just like default Angular Components do","archived":false,"fork":false,"pushed_at":"2022-12-10T00:55:10.000Z","size":1240,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-25T19:25:36.436Z","etag":null,"topics":["angular","components","custom-elements"],"latest_commit_sha":null,"homepage":"https://stackblitz.com/edit/angular-customelem-injector?file=src%2Fapp%2Fapp.module.ts","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/gund.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-07T23:48:59.000Z","updated_at":"2024-01-25T13:45:22.000Z","dependencies_parsed_at":"2023-01-25T20:17:18.321Z","dependency_job_id":null,"html_url":"https://github.com/gund/ngx-element-boundary","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/gund/ngx-element-boundary","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gund%2Fngx-element-boundary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gund%2Fngx-element-boundary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gund%2Fngx-element-boundary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gund%2Fngx-element-boundary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gund","download_url":"https://codeload.github.com/gund/ngx-element-boundary/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gund%2Fngx-element-boundary/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268844819,"owners_count":24316058,"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","status":"online","status_checked_at":"2025-08-05T02:00:12.334Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["angular","components","custom-elements"],"created_at":"2024-10-11T08:47:38.561Z","updated_at":"2025-10-18T06:17:46.365Z","avatar_url":"https://github.com/gund.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ngx-element-boundary\n\n\u003e Strategy for `@angular/elements` that allows to inherit `Injector`s\n\u003e between all Angular Custom Elements just like default Angular Component do\n\n## Compatibility table\n\n| Angular | ngx-element-boundary | NPM package                   |\n| ------- | -------------------- | ----------------------------- |\n| 14.x.x  | 2.x.x                | `ngx-element-boundary@^2.0.0` |\n| 10.x.x  | 1.x.x                | `ngx-element-boundary@^1.0.0` |\n| 9.x.x   | 1.x.x                | `ngx-element-boundary@^1.0.0` |\n\n_NOTE:_ For Angular versions below v10 it may work but was not tested.\n\n## Install\n\n```bash\n$ npm install ngx-element-boundary\n```\n\n## Why\n\nMain limitation when exposing Angular Components as Custom Elements\nis that their `Injector`s will not inherit properly when placed\nin proper hierarchy in the DOM tree.\n\nHowever this is expected behavior when using classical Angular Components -\ntheir `Injector`s are properly inherited and you a lot of times rely on it\nto implement nice patterns.\n\n_Solves https://github.com/angular/angular/issues/24824_\n\n## How\n\nBy default `@angular/elements` allows you to convert any Angular Component\ninto Custom Element with the limitation above.\n\nIt also allows to override default `NgElementStrategy` that is used inside\nto manage conversion process from Angular Component to Custom Element.\n\nThis library implements\n[`CrossBoundaryNgElementStrategy`](projects/ngx-element-boundary/src/lib/cross-boundary-ng-element-strategy.ts)\nthat is capable of tracking Angular Custom Elements created in DOM\nand setting up proper `Injector` chain between them.\n\nIt also does not re-implement default `NgElementStrategy` but requires\nyou to pass base strategy factory into it's own factory.\n\nTo simplify use-case there is an extractor factory of default\n`NgElementStrategy` that is provided by `@angular/elements` -\n[`DefaultElementBoundaryNgElementStrategyFactory`](projects/ngx-element-boundary/element-strategy/default/src/element-boundary-ng-element-strategy.ts)\n\n## Usage\n\nAll you have to do is to use custom `NgElementStrategy` called\n[`CrossBoundaryNgElementStrategy`](projects/ngx-element-boundary/src/lib/cross-boundary-ng-element-strategy.ts)\nwhen you are converting your Angular Component to Custom Element:\n\n```ts\nimport { Component } from '@angular/core';\nimport { createCustomElement } from '@angular/element';\nimport { CrossBoundaryNgElementStrategyFactory } from 'ngx-element-boundary';\nimport { DefaultElementBoundaryNgElementStrategyFactory } from 'ngx-element-boundary/element-strategy/default';\n\n@Component()\nclass MyAwesomeComponent {}\n\n// First create the default strategy\nconst defaultElementBoundaryStrategyFactory = new DefaultElementBoundaryNgElementStrategyFactory(\n  MyAwesomeComponent,\n  injector,\n);\n\n// Then create the cross boundary strategy that uses the default one\nconst connectedNgElementStrategyFactory = new CrossBoundaryNgElementStrategyFactory(\n  defaultElementBoundaryStrategyFactory,\n  {\n    isRoot: true, // Set to `true` for ONLY top-level custom element\n  },\n);\n\nconst MyAwesomeCustomElement = createCustomElement(MyAwesomeComponent, {\n  injector: injector,\n  strategyFactory: connectedNgElementStrategyFactory,\n});\n\ncustomElements.define('my-awesome', MyAwesomeCustomElement);\n```\n\nAs long as your Custom Elements are created using `CrossBoundaryNgElementStrategy`\nthey will properly inherit each other `Injector`s.\n\n### Template Injector\n\nMost of the times when your component projects content in template\nit does so in specific place in the view that may have it's own\ntree of `Injector`s.\n\nAnd by default the strategy will only inherit component level `Injector`s\neven if the projection was done on a deeper level.\n\nIn that case projected Custom Element will see top level `Injector`\nof the parent Custom Element and not the one it projected into.\n\nTo fix this issue you may tell the library where exactly you are having\ncontent projection in your view by using\n[`ElementBoundaryDirective`](projects/ngx-element-boundary/src/lib/element-boundary.directive.ts).\n\nSo in your component's template mark content projection with the directive:\n\n```html\n\u003csome-ng-component\u003e\n  \u003cdiv nebElementBoundary\u003e\n    \u003cng-content\u003e\u003c/ng-content\u003e\n  \u003c/div\u003e\n\u003c/some-ng-component\u003e\n```\n\n_NOTE:_ This directive is exported from `ElementBoundaryModule`.\n\nOnce you do that - any projected Custom Element will resolve `Injector`\nat the level that `ElementBoundaryDirective` is at, meaning that -\nCustom Element will be able to inject `some-ng-component`.\n\n## Base Strategy\n\nAs you might have already understood - this library does not re-implement\nthe default `NgElementStrategy` but only augments the base strategy by\nsetting up proper `Injector` tree between Custom Elements.\n\nThat means that the strategy\n[`CrossBoundaryNgElementStrategy`](projects/ngx-element-boundary/src/lib/cross-boundary-ng-element-strategy.ts)\nrequires you to pass another strategy.\n\nThat other strategy is not same as `NgElementStrategy` as it needs\naccess to the `ComponentRef` to be able to get Custom Element's `Injector`.\n\nFor that purpose library defines new version of `NgElementStrategy` called -\n[`ElementBoundaryNgElementStrategy`](projects/ngx-element-boundary/src/lib/element-boundary-ng-element-strategy.ts).\n\nIt also defines new version of `NgElementStrategyFactory` called -\n[`ElementBoundaryNgElementStrategyFactory`](projects/ngx-element-boundary/src/lib/element-boundary-ng-element-strategy.ts).\n\n## Default Strategy\n\nIn most cases you would want to reuse the same `NgElementStrategy`\nthat `@angular/elements` uses by default.\n\nFor this purpose library has secondary entry-point that contains\nall the functionality required - `ngx-element-boundary/element-strategy/default`.\n\nIn general you should use\n[`DefaultElementBoundaryNgElementStrategyFactory`](projects/ngx-element-boundary/element-strategy/default/src/element-boundary-ng-element-strategy.ts)\nas the base `ElementBoundaryNgElementStrategyFactory`.\n\nWhat it does is the following:\n\n- Uses strategy `DefaultNgElementStrategyFactoryStrategy` to\n  create default `NgElementStrategyFactory`\n- Uses `DefaultElementBoundaryNgElementStrategy` to bridge\n  between default `NgElementStrategy` and `ElementBoundaryNgElementStrategy`\n\nBy default it uses built-in way to extract default `NgElementStrategyFactory`.\nAnd because Angular Team decided to not expose it as part of public API\nthere are some private API accesses involved and they may brake at any time.\n\nShould that brake - you may still recover by providing updated functions\nto access private APIs all without the need to wait for new release.\n\nThere are 2 places where private API access is performed:\n\n- To extract `NgElementStrategy` from the Custom Element:\n  Performed in the\n  [`DefaultNgElementStrategyFactory`](projects/ngx-element-boundary/element-strategy/default/src/default-ng-element-strategy.ts)\n  via the `NgElementStrategyExtractor`.\n  You may provide custom extractor in `DefaultNgElementStrategyFactoryOptions`.\n- To extract `ComponentRef` from the `NgElementStrategy`:\n  Performed in the\n  [`DefaultElementBoundaryNgElementStrategy`](projects/ngx-element-boundary/element-strategy/default/src/element-boundary-ng-element-strategy.ts)\n  via the `NgElementStrategyComponentRefExtractor`.\n  You may provide custom extractor in `DefaultElementBoundaryNgElementStrategyOptions`.\n\nCreation of the default `NgElementStrategy` is done in\n[`DefaultNgElementStrategyFactory`](projects/ngx-element-boundary/element-strategy/default/src/default-ng-element-strategy.ts)\nby creating a dummy Custom Element using `createCustomElement()` function\nfrom the `@angular/elements` with default option for the strategy.\n\nIf you have a better way of creating the default `NgElementStrategy`\nyou may implement it as `DefaultNgElementStrategyFactoryStrategy` and then provide it in\n[`DefaultElementBoundaryNgElementStrategyFactoryOptions.factoryStrategy`](projects/ngx-element-boundary/element-strategy/default/src/element-boundary-ng-element-strategy.ts).\n\n_NOTE:_ Default strategy extraction was inspired by https://github.com/remackgeek/elements-zone-strategy\n\n---\n\nThis project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.0.1.\n\n## Development server\n\nRun `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.\n\n## Code scaffolding\n\nRun `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.\n\n## Build\n\nRun `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.\n\n## Running unit tests\n\nRun `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).\n\n## Running end-to-end tests\n\nRun `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).\n\n## Further help\n\nTo get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgund%2Fngx-element-boundary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgund%2Fngx-element-boundary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgund%2Fngx-element-boundary/lists"}