{"id":13808814,"url":"https://github.com/ncstate-sat/popover","last_synced_at":"2026-04-04T16:50:26.476Z","repository":{"id":25008804,"uuid":"102900761","full_name":"ncstate-sat/popover","owner":"ncstate-sat","description":"Popover component for Angular","archived":false,"fork":false,"pushed_at":"2025-12-02T03:53:17.000Z","size":7315,"stargazers_count":226,"open_issues_count":36,"forks_count":45,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-12-03T08:36:57.833Z","etag":null,"topics":["angular","angular-component","overlay","popover","popup"],"latest_commit_sha":null,"homepage":"","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/ncstate-sat.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-09-08T20:14:30.000Z","updated_at":"2025-11-30T22:33:33.000Z","dependencies_parsed_at":"2024-05-02T18:51:29.616Z","dependency_job_id":"9cedb95a-6ad9-49b8-87ca-67314710969f","html_url":"https://github.com/ncstate-sat/popover","commit_stats":{"total_commits":189,"total_committers":17,"mean_commits":"11.117647058823529","dds":0.5291005291005291,"last_synced_commit":"ea2dff9ce1213a5f1f8904d821d1e10efd672b25"},"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/ncstate-sat/popover","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncstate-sat%2Fpopover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncstate-sat%2Fpopover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncstate-sat%2Fpopover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncstate-sat%2Fpopover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ncstate-sat","download_url":"https://codeload.github.com/ncstate-sat/popover/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncstate-sat%2Fpopover/sbom","scorecard":{"id":677556,"data":{"date":"2025-08-11","repo":{"name":"github.com/ncstate-sat/popover","commit":"f5fbc145449335f6b2e012bf0976642f56a3083d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"Code-Review","score":3,"reason":"Found 10/26 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":2,"reason":"2 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 23 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-xffm-g5w8-qvg7","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T21:59:26.155Z","repository_id":25008804,"created_at":"2025-08-21T21:59:26.155Z","updated_at":"2025-08-21T21:59:26.155Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31406314,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: 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":["angular","angular-component","overlay","popover","popup"],"created_at":"2024-08-04T01:01:52.541Z","updated_at":"2026-04-04T16:50:26.441Z","avatar_url":"https://github.com/ncstate-sat.png","language":"TypeScript","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Tooltips"],"readme":"# Popover Component for Angular\n\n[![npm version](https://badge.fury.io/js/%40ncstate%2Fsat-popover.svg)](https://badge.fury.io/js/%40ncstate%2Fsat-popover)\n[![Build Status](https://travis-ci.org/ncstate-sat/popover.svg?branch=master)](https://travis-ci.org/ncstate-sat/popover)\n\n[Demo](https://stackblitz.com/edit/ncstate-sat-popover-examples) |\n[StackBlitz Template](https://stackblitz.com/edit/ncstate-sat-popover-issues) |\n[Development App](https://ncstate-sat.github.io/popover/)\n\n## Installation\n\n`sat-popover` has a peer dependency on the Angular CDK to leverage its overlay API.\n\n```bash\nnpm install --save @ncstate/sat-popover @angular/cdk\n```\n\n```ts\nimport { AppRootComponent } from './app-root.component';\nimport { bootstrapApplication } from '@angular/platform-browser';\nimport { importProvidersFrom } from '@angular/core';\nimport { provideAnimations, provideNoopAnimations } from '@angular/platform-browser/animations';\nimport { provideAnimationsAsync } from '@angular/platform-browser/animations/async';\nimport { SatPopoverModule } from '@ncstate/sat-popover';\n\nbootstrapApplication(AppRootComponent, {\n  // AppConfig\n  providers: [\n    // If you want the popover animations to work, you must use `provideAnimations` or `provideAnimationsAsync`.\n    provideAnimationsAsync(),\n\n    // If your application requires animations on immediate load, use `provideAnimations` instead.\n    // provideAnimations(),\n\n    // If you prefer to not have animations, you can use `provideNoopAnimations`.\n    // provideNoopAnimations(),\n\n    importProvidersFrom(SatPopoverModule)\n  ]\n});\n```\n\nFinally, import the `SatPopoverModule` as needed to provide the necessary components and directives.\n\n```ts\nimport { Component } from '@angular/core';\nimport { SatPopoverAnchorDirective, SatPopoverComponent } from '@ncstate/sat-popover';\n\n@Component({\n  imports: [ SatPopoverAnchorDirective, SatPopoverComponent ],\n  selector: 'my-component',\n  template: `\n    \u003cbutton [satPopoverAnchor]=\"myPopover\"\n      (mouseenter)=\"myPopover.open()\"\n      (mouseleave)=\"myPopover.close()\"\u003eHover me\u003c/button\u003e\n    \u003csat-popover #myPopover\u003eHello!\u003c/sat-popover\u003e\n  `\n})\n```\n\n## Usage\n\n### Getting started\n\nWrap any component you want to display in a popover with an `\u003csat-popover\u003e` component.\n\n```html\n\u003csat-popover\u003e\n  \u003capp-contact-overview [contact]=\"myContact\"\u003e\u003c/app-contact-overview\u003e\n\u003c/sat-popover\u003e\n```\n\nNext, apply the `satPopoverAnchor` directive to the element you wish to be the popover anchor and pass the `\u003csat-popover\u003e` component as an argument to the `satPopoverAnchor` directive.\n\n```html\n\u003cbutton [satPopoverAnchor]=\"popover\" (click)=\"popover.toggle()\"\u003e See Contact Details \u003c/button\u003e\n\n\u003csat-popover #popover hasBackdrop\u003e\n  \u003capp-contact-overview [contact]=\"myContact\"\u003e\u003c/app-contact-overview\u003e\n\u003c/sat-popover\u003e\n```\n\n\u003e Note: `hasBackdrop` is explained below\n\nAlternatively, supply an anchor element to the popover.\n\n```html\n\u003cbutton satPopoverAnchor #anchor=\"satPopoverAnchor\" (click)=\"anchor.popover.toggle()\"\u003e See Contact Details \u003c/button\u003e\n\n\u003csat-popover [anchor]=\"anchor\" hasBackdrop\u003e\n  \u003capp-contact-overview [contact]=\"myContact\"\u003e\u003c/app-contact-overview\u003e\n\u003c/sat-popover\u003e\n```\n\n### Alignment\n\nBy default, the popover will appear centered over the anchor. If you instead want the popover\nto appear below the anchor:\n\n```html\n\u003csat-popover verticalAlign=\"below\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\nYou can use the following to align the popover around the anchor:\n\n| Input             | Type                                                | Default  |\n| ----------------- | --------------------------------------------------- | -------- |\n| `horizontalAlign` | 'before' \\| 'start' \\| 'center' \\| 'end' \\| 'after' | 'center' |\n| `verticalAlign`   | 'above' \\| 'start' \\| 'center' \\| 'end' \\| 'below'  | 'center' |\n\nFor convenience, you can also use `xAlign` and `yAlign` as shorthand for `horizontalAlign`\nand `verticalAlign`, respectively.\n\nBy default, if the popover cannot fully fit within the viewport, it will use a fallback\nalignment. You can use `forceAlignment` to ensure that the popover always displays\nwith the alignment you've specified.\n\n```html\n\u003csat-popover verticalAlign=\"below\" forceAlignment\u003e\n  \u003c!-- This will always open below the anchor, even if it falls outside the viewport. --\u003e\n\u003c/sat-popover\u003e\n```\n\nAlso by default, as the user scrolls or changes the viewport size, the popover will attempt\nto stay within the viewport by using a fallback position (provided `forceAlignment` is not\nset). You can use `lockAlignment` to ensure the popover does not change its alignment once\nopened.\n\n```html\n\u003csat-popover lockAlignment\u003e\n  \u003c!-- This will open as normal, but not change alignment while open. --\u003e\n\u003c/sat-popover\u003e\n```\n\n### Opening and closing\n\nYou are in full control of when the popover opens and closes. You can hook into any event or\ntrigger that fits your application's needs.\n\n#### `SatPopover` has the following methods and outputs\n\n| Method  | Description                                  |\n| ------- | -------------------------------------------- |\n| open    | Open the popover.                            |\n| close   | Close the popover. Optionally takes a value. |\n| toggle  | Toggle the popover open or closed.           |\n| isOpen  | Get whether the popover is presently open.   |\n| realign | Realign the popover to the anchor.           |\n\n| Output          | Description                                                       |\n| --------------- | ----------------------------------------------------------------- |\n| opened          | Emits when the popover is opened.                                 |\n| closed          | Emits when the popover is closed.                                 |\n| afterOpen       | Emits when the popover has finished opening.                      |\n| afterClose      | Emits when the popover has finished closing.                      |\n| backdropClicked | Emits when the popover's backdrop (if enabled) is clicked.        |\n| overlayKeydown  | Emits when a keydown event is targeted to this popover's overlay. |\n\n#### `SatPopoverAnchor` has the following properties\n\n| Property                  | Description                                       |\n| ------------------------- | ------------------------------------------------- |\n| popover                   | A handle to the associated popover.               |\n| satPopoverAnchor (setter) | An `@Input()` for setting the associated popover. |\n| elementRef                | The ElementRef for with the anchor.               |\n| viewContainerRef          | The ViewContainerRef for the anchor.              |\n\n### Focus behavior\n\nBy default, the popover will apply focus to the first tabbable element when opened and trap focus\nwithin the popover until closed. If the popover does not contain any focusable elements, focus\nwill remain on the most recently focused element.\n\nYou can target a different element for initial focus using the `cdkFocusInitial` attribute.\n\nTo prevent focus from automatically moving into the popover, you can set the `autoFocus` property\nto `false`.\n\n```html\n\u003csat-popover [autoFocus]=\"false\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\nOnce the popover is closed, focus will return to the most recently focused element prior to\nopening the popover. To disable this, you can set the `restoreFocus` property to `false`.\n\n```html\n\u003csat-popover [restoreFocus]=\"false\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\nAlternatively the `open` method supports an optional `SatPopoverOpenOptions`\nobject where `autoFocus` and `restoreFocus` options can be set while opening the popover. Note\nthat these options do no take precendence over the component inputs. For example, if `restoreFocus`\nis set to `false` either in the open options or via the component input, focus will not be\nrestored.\n\n```html\n\u003cbutton (click)=\"popover.open({ restoreFocus: false })\"\u003e Open \u003c/button\u003e\n```\n\n### Backdrop\n\nYou can add a fullscreen backdrop that appears behind the popover when it is open. It prevents\ninteraction with the rest of the application and will automatically close the popover when\nclicked. To add it to your popover, use `hasBackdrop`.\n\n```html\n\u003csat-popover #myBlockingPopover hasBackdrop\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\nIf used, the default backdrop will be transparent. You can add any custom backdrop class with\n`backdropClass`.\n\n```html\n\u003csat-popover #myBlockingPopover hasBackdrop backdropClass=\"app-fancy-backdrop\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\n\u003e Note: if you plan on using `mouseenter` and `mouseleave` events to open and close your popover,\n\u003e keep in mind that a backdrop will block pointer events once it is open, immediately triggering\n\u003e a `mouseleave` event.\n\n### Overlay panel\n\nYou can add custom css classes to the overlay panel that wraps the popover.\n\n```html\n\u003csat-popover panelClass=\"app-fancy-panel\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\n### Interactive closing\n\nIf your popover has a backdrop, it will automatically close when clicked. The popover will also\nautomatically close when \u003ckbd\u003eesc\u003c/kbd\u003e is pressed. These two behaviors are wrapped in the\n`interactiveClose` property, which defaults to `true`. Set `interactiveClose` to `false` to prevent\nthe popover from automatically closing on these user interactions.\n\n```html\n\u003csat-popover hasBackdrop [interactiveClose]=\"false\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\nIf you wish to only disable the automatic \u003ckbd\u003eesc\u003c/kbd\u003e behavior, you must disable all\ninteractive close options and then manually react to `backdropClicked` events.\n\n```html\n\u003csat-popover #p hasBackdrop [interactiveClose]=\"false\" (backdropClicked)=\"p.close()\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\n### Scrolling\n\nBy default, when a popover is open and the user scrolls the container, the popover will reposition\nitself to stay attached to its anchor. You can adjust this behavior with `scrollStrategy`.\n\n```html\n\u003csat-popover #importantPopover scrollStrategy=\"block\"\u003e\n  \u003c!-- so important that the user must interact with it --\u003e\n\u003c/sat-popover\u003e\n```\n\n| Strategy       | Description                                 |\n| -------------- | ------------------------------------------- |\n| `'noop'`       | Don't update position.                      |\n| `'block'`      | Block page scrolling while open.            |\n| `'reposition'` | Reposition the popover on scroll (default). |\n| `'close'`      | Close the popover on scroll.                |\n\n\u003e Note: if your popover fails to stay anchored with the `reposition` strategy, you may need to add\n\u003e the [`cdkScrollable`](https://material.angular.io/cdk/scrolling/overview) directive to your\n\u003e scrolling container. This will ensure scroll events are dispatched to the popover's positioning\n\u003e service.\n\n### Animations\n\nBy default, the opening and closing animations of a popover are quick with a simple easing curve.\nYou can modify these animation curves using `openTransition` and `closeTransition`.\n\n```html\n\u003c!-- open slowly but close quickly --\u003e\n\u003csat-popover #mySlowPopover openTransition=\"1000ms ease-out\" closeTransition=\"100ms ease-in\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\nYou can also modify the default transition globally by adding a custom value to the\n`DEFAULT_TRANSITION` provider.\n\n```ts\nimport { SatPopoverModule, DEFAULT_TRANSITION } from '@ncstate/sat-popover';\n\n@NgModule({\n  ...\n  imports: [ SatPopoverModule ],\n  providers: [\n    { provide: DEFAULT_TRANSITION, useValue: '300ms ease' }\n  ]\n  ...\n})\nexport class AppModule { }\n```\n\nAdditionally you can modify the scale values for the opening (`startAtScale`) and closing (`endAtScale`) animations.\n\n```html\n\u003c!-- very subtle scale animation --\u003e\n\u003csat-popover #mySubtlePopover openAnimationStartAtScale=\"0.95\" closeAnimationEndAtScale=\"0.95\"\u003e\n  \u003c!-- ... --\u003e\n\u003c/sat-popover\u003e\n```\n\n## Styles\n\nThe `\u003csat-popover\u003e` component only provides styles to affect its own transform origin. It is\nthe responsibility of the elements you project inside the popover to style themselves. This\nincludes background color, box shadows, margin offsets, etc.\n\n## Add-on behaviors\n\n### Hover\n\nThe `SatPopoverHoverDirective` is available as a way to automatically add hover logic to your\nanchor with an optional delay. The `SatPopoverHoverDirective` must be used in conjunction\nwith `SatPopoverAnchor`.\n\n```html\n\u003cdiv satPopoverAnchor [satPopoverHover]=\"1000\"\u003e Hover to show tooltip after 1 second \u003c/div\u003e\n```\n\n```html\n\u003cdiv satPopoverAnchor\u003e Hover \u003cspan satPopoverHover\u003ethis text\u003c/span\u003e to show tooltip immediately \u003c/div\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fncstate-sat%2Fpopover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fncstate-sat%2Fpopover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fncstate-sat%2Fpopover/lists"}