@primer/behaviors 1.1.2 → 1.2.0-rc.5aa5da2

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/CHANGELOG.md ADDED
@@ -0,0 +1,51 @@
1
+ # @primer/behaviors
2
+
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#134](https://github.com/primer/behaviors/pull/134) [`cc5bf8e`](https://github.com/primer/behaviors/commit/cc5bf8e8404594bc6b3ff1493f253b171bfb03c0) Thanks [@jonrohan](https://github.com/jonrohan)! - Add Dimensions behavior
8
+
9
+ ## 1.1.3
10
+
11
+ ### Patch Changes
12
+
13
+ - [#93](https://github.com/primer/behaviors/pull/93) [`e5aaf68`](https://github.com/primer/behaviors/commit/e5aaf688b084bf6e425c6bdb0963aa50aacf8fa4) Thanks [@siddharthkp](https://github.com/siddharthkp)! - Anchored position: Add check for boundary collision on left side
14
+
15
+ ## 1.1.2
16
+
17
+ ### Patch Changes
18
+
19
+ - [#78](https://github.com/primer/behaviors/pull/78) [`62e5459`](https://github.com/primer/behaviors/commit/62e545913dae8ca42f88fd6184f190cdf3df9c4c) Thanks [@siddharthkp](https://github.com/siddharthkp)! - Anchored Position: Add alternative alignments to flip to if there isn't enough space
20
+
21
+ ## 1.1.1
22
+
23
+ ### Patch Changes
24
+
25
+ - [#73](https://github.com/primer/behaviors/pull/73) [`a96d60f`](https://github.com/primer/behaviors/commit/a96d60fdb2a2ffdde71a22ea29fa2c788bf4c6aa) Thanks [@dgreif](https://github.com/dgreif)! - Add `import` conditional export type to the package for better NodeJS ESM compatibility
26
+
27
+ ## 1.1.0
28
+
29
+ ### Minor Changes
30
+
31
+ - [#52](https://github.com/primer/behaviors/pull/52) [`1aa3027`](https://github.com/primer/behaviors/commit/1aa302782e3c833f9d9c27f602a046e81f05c3e5) Thanks [@owenniblock](https://github.com/owenniblock)! - Update focusTrap to use new methodology after accessibility discussions
32
+
33
+ ## 1.0.3
34
+
35
+ ### Patch Changes
36
+
37
+ - [#42](https://github.com/primer/behaviors/pull/42) [`41945a3`](https://github.com/primer/behaviors/commit/41945a37ef07da82ce5a29feb03d7a7d96ec76ea) Thanks [@dgreif](https://github.com/dgreif)! - Build both esm and cjs output for the package
38
+
39
+ ## 1.0.2
40
+
41
+ ### Patch Changes
42
+
43
+ - [#17](https://github.com/primer/behaviors/pull/17) [`9194ba4`](https://github.com/primer/behaviors/commit/9194ba403502b4acba0be03bed1a765c1ba81340) Thanks [@dgreif](https://github.com/dgreif)! - Correct margin orientation for `scrollIntoView`
44
+
45
+ * [#18](https://github.com/primer/behaviors/pull/18) [`3b4dd41`](https://github.com/primer/behaviors/commit/3b4dd414175417f83bd144939fe74b2a01bc7136) Thanks [@dgreif](https://github.com/dgreif)! - Export utils as submodule
46
+
47
+ ## 1.0.1
48
+
49
+ ### Patch Changes
50
+
51
+ - [#10](https://github.com/primer/behaviors/pull/10) [`88b6f34`](https://github.com/primer/behaviors/commit/88b6f34bf4874f3c81473020a01a58b197dd6e16) Thanks [@dgreif](https://github.com/dgreif)! - Set up changesets
@@ -233,6 +233,7 @@ function shouldRecalculateAlignment(align, currentPos, containerDimensions, elem
233
233
  return currentPos.left < containerDimensions.left;
234
234
  }
235
235
  else if (align === 'start' || align === 'center') {
236
- return currentPos.left + elementDimensions.width > containerDimensions.left + containerDimensions.width;
236
+ return (currentPos.left + elementDimensions.width > containerDimensions.left + containerDimensions.width ||
237
+ currentPos.left < containerDimensions.left);
237
238
  }
238
239
  }
@@ -0,0 +1,19 @@
1
+ declare type Dimensions = {
2
+ top: number;
3
+ left: number;
4
+ bottom: number;
5
+ right: number;
6
+ height?: number;
7
+ width?: number;
8
+ };
9
+ declare type Offset = {
10
+ top: number;
11
+ left: number;
12
+ };
13
+ export declare function offset(element: HTMLElement): Offset;
14
+ export declare function overflowParent(targetElement: HTMLElement): HTMLElement | null | undefined;
15
+ export declare function overflowOffset(element: HTMLElement, targetContainer: Document | HTMLElement | null): Dimensions | undefined;
16
+ export declare function positionedOffset(targetElement: HTMLElement, container: HTMLElement | Document | Window | null): (Dimensions & {
17
+ _container: HTMLElement;
18
+ }) | undefined;
19
+ export {};
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.positionedOffset = exports.overflowOffset = exports.overflowParent = exports.offset = void 0;
4
+ function offset(element) {
5
+ const rect = element.getBoundingClientRect();
6
+ return {
7
+ top: rect.top + window.pageYOffset,
8
+ left: rect.left + window.pageXOffset
9
+ };
10
+ }
11
+ exports.offset = offset;
12
+ function overflowParent(targetElement) {
13
+ let element = targetElement;
14
+ const document = element.ownerDocument;
15
+ if (!document) {
16
+ return;
17
+ }
18
+ if (!element.offsetParent) {
19
+ return;
20
+ }
21
+ const HTMLElement = document.defaultView.HTMLElement;
22
+ if (element === document.body) {
23
+ return;
24
+ }
25
+ while (element !== document.body) {
26
+ if (element.parentElement instanceof HTMLElement) {
27
+ element = element.parentElement;
28
+ }
29
+ else {
30
+ return;
31
+ }
32
+ const { position, overflowY, overflowX } = getComputedStyle(element);
33
+ if (position === 'fixed' ||
34
+ overflowY === 'auto' ||
35
+ overflowX === 'auto' ||
36
+ overflowY === 'scroll' ||
37
+ overflowX === 'scroll') {
38
+ break;
39
+ }
40
+ }
41
+ return element instanceof Document ? null : element;
42
+ }
43
+ exports.overflowParent = overflowParent;
44
+ function overflowOffset(element, targetContainer) {
45
+ let container = targetContainer;
46
+ const document = element.ownerDocument;
47
+ if (!document) {
48
+ return;
49
+ }
50
+ const documentElement = document.documentElement;
51
+ if (!documentElement) {
52
+ return;
53
+ }
54
+ if (element === documentElement) {
55
+ return;
56
+ }
57
+ const elementOffset = positionedOffset(element, container);
58
+ if (!elementOffset) {
59
+ return;
60
+ }
61
+ container = elementOffset._container;
62
+ const scroll = container === document.documentElement && document.defaultView
63
+ ? {
64
+ top: document.defaultView.pageYOffset,
65
+ left: document.defaultView.pageXOffset
66
+ }
67
+ : {
68
+ top: container.scrollTop,
69
+ left: container.scrollLeft
70
+ };
71
+ const top = elementOffset.top - scroll.top;
72
+ const left = elementOffset.left - scroll.left;
73
+ const height = container.clientHeight;
74
+ const width = container.clientWidth;
75
+ const bottom = height - (top + element.offsetHeight);
76
+ const right = width - (left + element.offsetWidth);
77
+ return { top, left, bottom, right, height, width };
78
+ }
79
+ exports.overflowOffset = overflowOffset;
80
+ function positionedOffset(targetElement, container) {
81
+ let element = targetElement;
82
+ const document = element.ownerDocument;
83
+ if (!document) {
84
+ return;
85
+ }
86
+ const documentElement = document.documentElement;
87
+ if (!documentElement) {
88
+ return;
89
+ }
90
+ const HTMLElement = document.defaultView.HTMLElement;
91
+ let top = 0;
92
+ let left = 0;
93
+ const height = element.offsetHeight;
94
+ const width = element.offsetWidth;
95
+ while (!(element === document.body || element === container)) {
96
+ top += element.offsetTop || 0;
97
+ left += element.offsetLeft || 0;
98
+ if (element.offsetParent instanceof HTMLElement) {
99
+ element = element.offsetParent;
100
+ }
101
+ else {
102
+ return;
103
+ }
104
+ }
105
+ let scrollHeight;
106
+ let scrollWidth;
107
+ let measuredContainer;
108
+ if (!container ||
109
+ container === document ||
110
+ container === document.defaultView ||
111
+ container === document.documentElement ||
112
+ container === document.body) {
113
+ measuredContainer = documentElement;
114
+ scrollHeight = getDocumentHeight(document.body, documentElement);
115
+ scrollWidth = getDocumentWidth(document.body, documentElement);
116
+ }
117
+ else if (container instanceof HTMLElement) {
118
+ measuredContainer = container;
119
+ scrollHeight = container.scrollHeight;
120
+ scrollWidth = container.scrollWidth;
121
+ }
122
+ else {
123
+ return;
124
+ }
125
+ const bottom = scrollHeight - (top + height);
126
+ const right = scrollWidth - (left + width);
127
+ return { top, left, bottom, right, _container: measuredContainer };
128
+ }
129
+ exports.positionedOffset = positionedOffset;
130
+ function getDocumentHeight(documentBody, documentElement) {
131
+ return Math.max(documentBody.scrollHeight, documentElement.scrollHeight, documentBody.offsetHeight, documentElement.offsetHeight, documentElement.clientHeight);
132
+ }
133
+ function getDocumentWidth(documentBody, documentElement) {
134
+ return Math.max(documentBody.scrollWidth, documentElement.scrollWidth, documentBody.offsetWidth, documentElement.offsetWidth, documentElement.clientWidth);
135
+ }
@@ -2,3 +2,4 @@ export * from './anchored-position.js';
2
2
  export * from './focus-trap.js';
3
3
  export * from './focus-zone.js';
4
4
  export * from './scroll-into-view.js';
5
+ export * from './dimensions.js';
package/dist/cjs/index.js CHANGED
@@ -14,3 +14,4 @@ __exportStar(require("./anchored-position.js"), exports);
14
14
  __exportStar(require("./focus-trap.js"), exports);
15
15
  __exportStar(require("./focus-zone.js"), exports);
16
16
  __exportStar(require("./scroll-into-view.js"), exports);
17
+ __exportStar(require("./dimensions.js"), exports);
@@ -229,6 +229,7 @@ function shouldRecalculateAlignment(align, currentPos, containerDimensions, elem
229
229
  return currentPos.left < containerDimensions.left;
230
230
  }
231
231
  else if (align === 'start' || align === 'center') {
232
- return currentPos.left + elementDimensions.width > containerDimensions.left + containerDimensions.width;
232
+ return (currentPos.left + elementDimensions.width > containerDimensions.left + containerDimensions.width ||
233
+ currentPos.left < containerDimensions.left);
233
234
  }
234
235
  }
@@ -0,0 +1,19 @@
1
+ declare type Dimensions = {
2
+ top: number;
3
+ left: number;
4
+ bottom: number;
5
+ right: number;
6
+ height?: number;
7
+ width?: number;
8
+ };
9
+ declare type Offset = {
10
+ top: number;
11
+ left: number;
12
+ };
13
+ export declare function offset(element: HTMLElement): Offset;
14
+ export declare function overflowParent(targetElement: HTMLElement): HTMLElement | null | undefined;
15
+ export declare function overflowOffset(element: HTMLElement, targetContainer: Document | HTMLElement | null): Dimensions | undefined;
16
+ export declare function positionedOffset(targetElement: HTMLElement, container: HTMLElement | Document | Window | null): (Dimensions & {
17
+ _container: HTMLElement;
18
+ }) | undefined;
19
+ export {};
@@ -0,0 +1,128 @@
1
+ export function offset(element) {
2
+ const rect = element.getBoundingClientRect();
3
+ return {
4
+ top: rect.top + window.pageYOffset,
5
+ left: rect.left + window.pageXOffset
6
+ };
7
+ }
8
+ export function overflowParent(targetElement) {
9
+ let element = targetElement;
10
+ const document = element.ownerDocument;
11
+ if (!document) {
12
+ return;
13
+ }
14
+ if (!element.offsetParent) {
15
+ return;
16
+ }
17
+ const HTMLElement = document.defaultView.HTMLElement;
18
+ if (element === document.body) {
19
+ return;
20
+ }
21
+ while (element !== document.body) {
22
+ if (element.parentElement instanceof HTMLElement) {
23
+ element = element.parentElement;
24
+ }
25
+ else {
26
+ return;
27
+ }
28
+ const { position, overflowY, overflowX } = getComputedStyle(element);
29
+ if (position === 'fixed' ||
30
+ overflowY === 'auto' ||
31
+ overflowX === 'auto' ||
32
+ overflowY === 'scroll' ||
33
+ overflowX === 'scroll') {
34
+ break;
35
+ }
36
+ }
37
+ return element instanceof Document ? null : element;
38
+ }
39
+ export function overflowOffset(element, targetContainer) {
40
+ let container = targetContainer;
41
+ const document = element.ownerDocument;
42
+ if (!document) {
43
+ return;
44
+ }
45
+ const documentElement = document.documentElement;
46
+ if (!documentElement) {
47
+ return;
48
+ }
49
+ if (element === documentElement) {
50
+ return;
51
+ }
52
+ const elementOffset = positionedOffset(element, container);
53
+ if (!elementOffset) {
54
+ return;
55
+ }
56
+ container = elementOffset._container;
57
+ const scroll = container === document.documentElement && document.defaultView
58
+ ? {
59
+ top: document.defaultView.pageYOffset,
60
+ left: document.defaultView.pageXOffset
61
+ }
62
+ : {
63
+ top: container.scrollTop,
64
+ left: container.scrollLeft
65
+ };
66
+ const top = elementOffset.top - scroll.top;
67
+ const left = elementOffset.left - scroll.left;
68
+ const height = container.clientHeight;
69
+ const width = container.clientWidth;
70
+ const bottom = height - (top + element.offsetHeight);
71
+ const right = width - (left + element.offsetWidth);
72
+ return { top, left, bottom, right, height, width };
73
+ }
74
+ export function positionedOffset(targetElement, container) {
75
+ let element = targetElement;
76
+ const document = element.ownerDocument;
77
+ if (!document) {
78
+ return;
79
+ }
80
+ const documentElement = document.documentElement;
81
+ if (!documentElement) {
82
+ return;
83
+ }
84
+ const HTMLElement = document.defaultView.HTMLElement;
85
+ let top = 0;
86
+ let left = 0;
87
+ const height = element.offsetHeight;
88
+ const width = element.offsetWidth;
89
+ while (!(element === document.body || element === container)) {
90
+ top += element.offsetTop || 0;
91
+ left += element.offsetLeft || 0;
92
+ if (element.offsetParent instanceof HTMLElement) {
93
+ element = element.offsetParent;
94
+ }
95
+ else {
96
+ return;
97
+ }
98
+ }
99
+ let scrollHeight;
100
+ let scrollWidth;
101
+ let measuredContainer;
102
+ if (!container ||
103
+ container === document ||
104
+ container === document.defaultView ||
105
+ container === document.documentElement ||
106
+ container === document.body) {
107
+ measuredContainer = documentElement;
108
+ scrollHeight = getDocumentHeight(document.body, documentElement);
109
+ scrollWidth = getDocumentWidth(document.body, documentElement);
110
+ }
111
+ else if (container instanceof HTMLElement) {
112
+ measuredContainer = container;
113
+ scrollHeight = container.scrollHeight;
114
+ scrollWidth = container.scrollWidth;
115
+ }
116
+ else {
117
+ return;
118
+ }
119
+ const bottom = scrollHeight - (top + height);
120
+ const right = scrollWidth - (left + width);
121
+ return { top, left, bottom, right, _container: measuredContainer };
122
+ }
123
+ function getDocumentHeight(documentBody, documentElement) {
124
+ return Math.max(documentBody.scrollHeight, documentElement.scrollHeight, documentBody.offsetHeight, documentElement.offsetHeight, documentElement.clientHeight);
125
+ }
126
+ function getDocumentWidth(documentBody, documentElement) {
127
+ return Math.max(documentBody.scrollWidth, documentElement.scrollWidth, documentBody.offsetWidth, documentElement.offsetWidth, documentElement.clientWidth);
128
+ }
@@ -2,3 +2,4 @@ export * from './anchored-position.js';
2
2
  export * from './focus-trap.js';
3
3
  export * from './focus-zone.js';
4
4
  export * from './scroll-into-view.js';
5
+ export * from './dimensions.js';
package/dist/esm/index.js CHANGED
@@ -2,3 +2,4 @@ export * from './anchored-position.js';
2
2
  export * from './focus-trap.js';
3
3
  export * from './focus-zone.js';
4
4
  export * from './scroll-into-view.js';
5
+ export * from './dimensions.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/behaviors",
3
- "version": "1.1.2",
3
+ "version": "1.2.0-rc.5aa5da2",
4
4
  "description": "Shared behaviors for JavaScript components",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",