ng-auto-position 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex/environments/environment.toml +14 -0
- package/.editorconfig +16 -0
- package/.vscode/extensions.json +4 -0
- package/.vscode/launch.json +20 -0
- package/.vscode/tasks.json +42 -0
- package/README.md +246 -200
- package/angular.json +143 -0
- package/dist/README.md +246 -0
- package/{esm2022 → dist/esm2022}/app/ng-auto-position/ng-auto-position.directive.mjs +1 -1
- package/{esm2022 → dist/esm2022}/public_api.mjs +1 -1
- package/dist/fesm2022/ng-auto-position.mjs.map +1 -0
- package/dist/ng-auto-position-0.0.9.tgz +0 -0
- package/docs/3rdpartylicenses.txt +271 -0
- package/docs/browser/404.html +14 -0
- package/docs/browser/index.html +14 -0
- package/docs/browser/main-T53CFXRG.js +26 -0
- package/docs/browser/polyfills-FFHMD2TL.js +2 -0
- package/docs/browser/styles-VEXJFBVJ.css +1 -0
- package/favicon.ico +0 -0
- package/ng-package.json +8 -0
- package/package.json +26 -17
- package/src/app/app.component.css +359 -0
- package/src/app/app.component.html +256 -0
- package/src/app/app.component.ts +49 -0
- package/src/app/app.config.ts +8 -0
- package/src/app/app.routes.ts +3 -0
- package/src/app/ng-auto-position/index.ts +1 -0
- package/src/app/ng-auto-position/ng-auto-position.directive.ts +199 -0
- package/src/app/ng-auto-position/testing/ng-autoposition-test.component.html +35 -0
- package/src/app/ng-auto-position/testing/ng-autoposition-test.component.ts +17 -0
- package/src/assets/.gitkeep +0 -0
- package/src/index.html +13 -0
- package/src/main.ts +7 -0
- package/src/public_api.ts +1 -0
- package/src/styles.css +31 -0
- package/tsconfig.app.json +14 -0
- package/tsconfig.json +34 -0
- package/tsconfig.spec.json +9 -0
- package/fesm2022/ng-auto-position.mjs.map +0 -1
- package/ng-auto-position-0.0.8.tgz +0 -0
- /package/{app → dist/app}/ng-auto-position/ng-auto-position.directive.d.ts +0 -0
- /package/{esm2022 → dist/esm2022}/ng-auto-position.mjs +0 -0
- /package/{fesm2022 → dist/fesm2022}/ng-auto-position.mjs +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{public_api.d.ts → dist/public_api.d.ts} +0 -0
package/.editorconfig
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Editor configuration, see https://editorconfig.org
|
|
2
|
+
root = true
|
|
3
|
+
|
|
4
|
+
[*]
|
|
5
|
+
charset = utf-8
|
|
6
|
+
indent_style = space
|
|
7
|
+
indent_size = 2
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
|
|
11
|
+
[*.ts]
|
|
12
|
+
quote_type = single
|
|
13
|
+
|
|
14
|
+
[*.md]
|
|
15
|
+
max_line_length = off
|
|
16
|
+
trim_trailing_whitespace = false
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"configurations": [
|
|
5
|
+
{
|
|
6
|
+
"name": "ng serve",
|
|
7
|
+
"type": "chrome",
|
|
8
|
+
"request": "launch",
|
|
9
|
+
"preLaunchTask": "npm: start",
|
|
10
|
+
"url": "http://localhost:4200/"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "ng test",
|
|
14
|
+
"type": "chrome",
|
|
15
|
+
"request": "launch",
|
|
16
|
+
"preLaunchTask": "npm: test",
|
|
17
|
+
"url": "http://localhost:9876/debug.html"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"tasks": [
|
|
5
|
+
{
|
|
6
|
+
"type": "npm",
|
|
7
|
+
"script": "start",
|
|
8
|
+
"isBackground": true,
|
|
9
|
+
"problemMatcher": {
|
|
10
|
+
"owner": "typescript",
|
|
11
|
+
"pattern": "$tsc",
|
|
12
|
+
"background": {
|
|
13
|
+
"activeOnStart": true,
|
|
14
|
+
"beginsPattern": {
|
|
15
|
+
"regexp": "(.*?)"
|
|
16
|
+
},
|
|
17
|
+
"endsPattern": {
|
|
18
|
+
"regexp": "bundle generation complete"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "npm",
|
|
25
|
+
"script": "test",
|
|
26
|
+
"isBackground": true,
|
|
27
|
+
"problemMatcher": {
|
|
28
|
+
"owner": "typescript",
|
|
29
|
+
"pattern": "$tsc",
|
|
30
|
+
"background": {
|
|
31
|
+
"activeOnStart": true,
|
|
32
|
+
"beginsPattern": {
|
|
33
|
+
"regexp": "(.*?)"
|
|
34
|
+
},
|
|
35
|
+
"endsPattern": {
|
|
36
|
+
"regexp": "bundle generation complete"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
package/README.md
CHANGED
|
@@ -1,200 +1,246 @@
|
|
|
1
|
-
# **ng-auto-position**
|
|
2
|
-
|
|
3
|
-
A lightweight **Angular standalone directive** that automatically positions dropdowns, popovers, and floating panels relative to a reference element, while correctly handling scrolling, resizing, viewport boundaries, and scroll locking.
|
|
4
|
-
|
|
5
|
-
This directive is designed for cases where **Angular CDK Overlay is too heavy**, but you still need **reliable, production-grade positioning**.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## **✨ Features**
|
|
10
|
-
|
|
11
|
-
* ✅ **Smart Positioning**: Auto positions popup **above or below** a reference element.
|
|
12
|
-
* ✅ **Dynamic Tracking**: Popup **follows the reference** while scrolling (no freezing).
|
|
13
|
-
* ✅ **Boundary Detection**: Viewport clamping when the reference is visible.
|
|
14
|
-
* ✅ **Natural Exit**: Popup moves out of viewport when the reference fully leaves.
|
|
15
|
-
* ✅ **Responsive**: Optional repositioning on scroll & resize.
|
|
16
|
-
* ✅ **Layout Sync**: Optional width matching with reference element.
|
|
17
|
-
* ✅ **UX Control**: Optional background scroll locking and internal scroll handling.
|
|
18
|
-
* ✅ **Modern**: Standalone directive (Angular 16+), no Angular CDK dependency.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## **📦 Installation**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
</
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
### **
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
1
|
+
# **ng-auto-position**
|
|
2
|
+
|
|
3
|
+
A lightweight **Angular standalone directive** that automatically positions dropdowns, popovers, and floating panels relative to a reference element, while correctly handling scrolling, resizing, viewport boundaries, and scroll locking.
|
|
4
|
+
|
|
5
|
+
This directive is designed for cases where **Angular CDK Overlay is too heavy**, but you still need **reliable, production-grade positioning**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## **✨ Features**
|
|
10
|
+
|
|
11
|
+
* ✅ **Smart Positioning**: Auto positions popup **above or below** a reference element.
|
|
12
|
+
* ✅ **Dynamic Tracking**: Popup **follows the reference** while scrolling (no freezing).
|
|
13
|
+
* ✅ **Boundary Detection**: Viewport clamping when the reference is visible.
|
|
14
|
+
* ✅ **Natural Exit**: Popup moves out of viewport when the reference fully leaves.
|
|
15
|
+
* ✅ **Responsive**: Optional repositioning on scroll & resize.
|
|
16
|
+
* ✅ **Layout Sync**: Optional width matching with reference element.
|
|
17
|
+
* ✅ **UX Control**: Optional background scroll locking and internal scroll handling.
|
|
18
|
+
* ✅ **Modern**: Standalone directive (Angular 16+), no Angular CDK dependency.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## **📦 Installation**
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install ng-auto-position
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm add ng-auto-position
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn add ng-auto-position
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## **🧪 Demo**
|
|
39
|
+
|
|
40
|
+
Run locally to see the live positioning demos and scroll playground.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install
|
|
44
|
+
npm start
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Open the dev server URL shown in your terminal.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## **📌 Quick Start**
|
|
52
|
+
|
|
53
|
+
### **1\. Component Template**
|
|
54
|
+
|
|
55
|
+
Apply the directive and provide the ID of the element it should anchor to.
|
|
56
|
+
|
|
57
|
+
HTML
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<button id="menuBtn">Menu</button>
|
|
61
|
+
|
|
62
|
+
<div
|
|
63
|
+
ngAutoPosition
|
|
64
|
+
referenceElementId="menuBtn"
|
|
65
|
+
[offset]="8"
|
|
66
|
+
[matchWidth]="true"
|
|
67
|
+
>
|
|
68
|
+
Menu content
|
|
69
|
+
</div>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
TypeScript
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { NgAutoPositionElementDirective } from 'ng-auto-position';
|
|
76
|
+
import { Component } from '@angular/core';
|
|
77
|
+
|
|
78
|
+
@Component({
|
|
79
|
+
selector: 'demo',
|
|
80
|
+
standalone: true,
|
|
81
|
+
imports: [NgAutoPositionElementDirective],
|
|
82
|
+
templateUrl: './demo.component.html',
|
|
83
|
+
})
|
|
84
|
+
export class DemoComponent {}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## **⚙️ API Inputs**
|
|
90
|
+
|
|
91
|
+
| Input | Type | Default | Description |
|
|
92
|
+
| :---- | :---- | :---- | :---- |
|
|
93
|
+
| referenceElementId | string | null | ID of the reference element. |
|
|
94
|
+
| enableAutoReposition | boolean | true | Reposition on window scroll & resize. |
|
|
95
|
+
| debounceMs | number | 0 | Debounce delay for scroll/resize events. |
|
|
96
|
+
| offset | number | 0 | Pixel gap between reference and popup. |
|
|
97
|
+
| matchWidth | boolean | false | Match popup width to reference element width. |
|
|
98
|
+
| scrollableSelector | string | null | Inner element selector to limit height/enable scroll. |
|
|
99
|
+
| hideScrollTargets | string[] | null | IDs or classes (e.g. ['body']) to hide scrollbars. |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## **✅ Common Recipes**
|
|
104
|
+
|
|
105
|
+
### **1\. Menu With Internal Scroll**
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<button id="menuBtn">Open menu</button>
|
|
109
|
+
|
|
110
|
+
<div
|
|
111
|
+
ngAutoPosition
|
|
112
|
+
referenceElementId="menuBtn"
|
|
113
|
+
[matchWidth]="true"
|
|
114
|
+
[scrollableSelector]="'.menu-items'"
|
|
115
|
+
[offset]="8"
|
|
116
|
+
>
|
|
117
|
+
<div class="menu-items">
|
|
118
|
+
<div class="menu-item">Account settings and profile preferences</div>
|
|
119
|
+
<div class="menu-item">Billing, invoices, and subscription plan</div>
|
|
120
|
+
<div class="menu-item">Team access and member permissions</div>
|
|
121
|
+
<div class="menu-item">Keyboard shortcuts and productivity tips</div>
|
|
122
|
+
<div class="menu-item">Security, sessions, and sign out</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```css
|
|
128
|
+
.menu-items {
|
|
129
|
+
overflow-y: auto;
|
|
130
|
+
max-height: 240px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.menu-item {
|
|
134
|
+
line-height: 1.35;
|
|
135
|
+
white-space: normal;
|
|
136
|
+
overflow-wrap: anywhere;
|
|
137
|
+
word-break: break-word;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### **2\. Scroll-Lock The Background**
|
|
142
|
+
|
|
143
|
+
```html
|
|
144
|
+
<button id="sheetBtn">Open sheet</button>
|
|
145
|
+
|
|
146
|
+
<div
|
|
147
|
+
ngAutoPosition
|
|
148
|
+
referenceElementId="sheetBtn"
|
|
149
|
+
[hideScrollTargets]="['body', '.app-shell']"
|
|
150
|
+
>
|
|
151
|
+
Content
|
|
152
|
+
</div>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### **3\. Auto-Width Popover**
|
|
156
|
+
|
|
157
|
+
```html
|
|
158
|
+
<button id="helpBtn">Help</button>
|
|
159
|
+
<div ngAutoPosition referenceElementId="helpBtn" [matchWidth]="true">
|
|
160
|
+
Helpful content
|
|
161
|
+
</div>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### **4\. Scroll Tracking (Window Scroll)**
|
|
165
|
+
|
|
166
|
+
```html
|
|
167
|
+
<button id="scrollAnchor">Anchor</button>
|
|
168
|
+
<div ngAutoPosition referenceElementId="scrollAnchor" [offset]="12">
|
|
169
|
+
This stays attached while the page scrolls.
|
|
170
|
+
</div>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## **🧩 Advanced Examples**
|
|
176
|
+
|
|
177
|
+
### **1\. Dropdown with internal scrolling**
|
|
178
|
+
|
|
179
|
+
Automatically constrains height and enables internal scrolling if the viewport is too small.
|
|
180
|
+
|
|
181
|
+
HTML
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
<button id="actionsBtn">Actions</button>
|
|
185
|
+
|
|
186
|
+
<div
|
|
187
|
+
ngAutoPosition
|
|
188
|
+
referenceElementId="actionsBtn"
|
|
189
|
+
scrollableSelector=".menu-items"
|
|
190
|
+
class="dropdown"
|
|
191
|
+
>
|
|
192
|
+
<div class="menu-items"></div>
|
|
193
|
+
</div>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
CSS
|
|
197
|
+
|
|
198
|
+
```css
|
|
199
|
+
.menu-items {
|
|
200
|
+
overflow-y: auto;
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### **2\. Lock background scrolling**
|
|
205
|
+
|
|
206
|
+
Prevents the user from scrolling the background while the popup is active.
|
|
207
|
+
|
|
208
|
+
HTML
|
|
209
|
+
|
|
210
|
+
```html
|
|
211
|
+
<div
|
|
212
|
+
ngAutoPosition
|
|
213
|
+
referenceElementId="menuBtn"
|
|
214
|
+
[hideScrollTargets]="['body', '.layout-container']"
|
|
215
|
+
class="dropdown"
|
|
216
|
+
>
|
|
217
|
+
Menu content
|
|
218
|
+
</div>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## **🧠 Positioning Behavior Explained**
|
|
224
|
+
|
|
225
|
+
* **Reference is fully visible**: Popup is clamped to the viewport to prevent overflow on all sides.
|
|
226
|
+
* **Reference is partially visible**: Popup remains visible and clamped to the viewport.
|
|
227
|
+
* **Reference is outside viewport**: Popup moves with the reference and can go fully off-screen. It never "freezes" or sticks in mid-air.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## **🧪 Angular Compatibility**
|
|
232
|
+
|
|
233
|
+
| Angular Version | Supported |
|
|
234
|
+
| :---- | :---- |
|
|
235
|
+
| 16+ | ✅ |
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## **📄 License**
|
|
240
|
+
|
|
241
|
+
MIT © Roshan
|
|
242
|
+
|
|
243
|
+
## **🔗 Links**
|
|
244
|
+
|
|
245
|
+
* **npm**: [https://www.npmjs.com/package/ng-auto-position](https://www.npmjs.com/package/ng-auto-position)
|
|
246
|
+
* **GitHub**: [https://github.com/roshan2197/ng-auto-position](https://github.com/roshan2197/ng-auto-position)
|