@primer/behaviors 1.1.0 → 1.1.2-rc.83d1cfb

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,39 @@
1
+ # @primer/behaviors
2
+
3
+ ## 1.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#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
8
+
9
+ ## 1.1.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [#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
14
+
15
+ ## 1.1.0
16
+
17
+ ### Minor Changes
18
+
19
+ - [#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
20
+
21
+ ## 1.0.3
22
+
23
+ ### Patch Changes
24
+
25
+ - [#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
26
+
27
+ ## 1.0.2
28
+
29
+ ### Patch Changes
30
+
31
+ - [#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`
32
+
33
+ * [#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
34
+
35
+ ## 1.0.1
36
+
37
+ ### Patch Changes
38
+
39
+ - [#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
@@ -11,5 +11,6 @@ export interface AnchorPosition {
11
11
  top: number;
12
12
  left: number;
13
13
  anchorSide: AnchorSide;
14
+ anchorAlign: AnchorAlignment;
14
15
  }
15
16
  export declare function getAnchoredPosition(floatingElement: Element, anchorElement: Element | DOMRect, settings?: Partial<PositionSettings>): AnchorPosition;
@@ -7,6 +7,11 @@ const alternateOrders = {
7
7
  'outside-left': ['outside-right', 'outside-bottom', 'outside-top', 'outside-bottom'],
8
8
  'outside-right': ['outside-left', 'outside-bottom', 'outside-top', 'outside-bottom']
9
9
  };
10
+ const alternateAlignments = {
11
+ start: ['end', 'center'],
12
+ end: ['start', 'center'],
13
+ center: ['end', 'start']
14
+ };
10
15
  function getAnchoredPosition(floatingElement, anchorElement, settings = {}) {
11
16
  const parentElement = getPositionedParent(floatingElement);
12
17
  const clippingRect = getClippingRect(parentElement);
@@ -86,6 +91,7 @@ function pureCalculateAnchoredPosition(viewportRect, relativePosition, floatingR
86
91
  };
87
92
  let pos = calculatePosition(floatingRect, anchorRect, side, align, anchorOffset, alignmentOffset);
88
93
  let anchorSide = side;
94
+ let anchorAlign = align;
89
95
  pos.top -= relativePosition.top;
90
96
  pos.left -= relativePosition.left;
91
97
  if (!allowOutOfBounds) {
@@ -103,6 +109,20 @@ function pureCalculateAnchoredPosition(viewportRect, relativePosition, floatingR
103
109
  anchorSide = nextSide;
104
110
  }
105
111
  }
112
+ const alternateAlignment = alternateAlignments[align];
113
+ let alignmentAttempt = 0;
114
+ if (alternateAlignment) {
115
+ let prevAlign = align;
116
+ while (alignmentAttempt < alternateAlignment.length &&
117
+ shouldRecalculateAlignment(prevAlign, pos, relativeViewportRect, floatingRect)) {
118
+ const nextAlign = alternateAlignment[alignmentAttempt++];
119
+ prevAlign = nextAlign;
120
+ pos = calculatePosition(floatingRect, anchorRect, anchorSide, nextAlign, anchorOffset, alignmentOffset);
121
+ pos.top -= relativePosition.top;
122
+ pos.left -= relativePosition.left;
123
+ anchorAlign = nextAlign;
124
+ }
125
+ }
106
126
  if (pos.top < relativeViewportRect.top) {
107
127
  pos.top = relativeViewportRect.top;
108
128
  }
@@ -118,7 +138,7 @@ function pureCalculateAnchoredPosition(viewportRect, relativePosition, floatingR
118
138
  }
119
139
  }
120
140
  }
121
- return Object.assign(Object.assign({}, pos), { anchorSide });
141
+ return Object.assign(Object.assign({}, pos), { anchorSide, anchorAlign });
122
142
  }
123
143
  function calculatePosition(elementDimensions, anchorPosition, side, align, anchorOffset, alignmentOffset) {
124
144
  const anchorRight = anchorPosition.left + anchorPosition.width;
@@ -208,3 +228,11 @@ function shouldRecalculatePosition(side, currentPos, containerDimensions, elemen
208
228
  currentPos.left + elementDimensions.width > containerDimensions.width + containerDimensions.left);
209
229
  }
210
230
  }
231
+ function shouldRecalculateAlignment(align, currentPos, containerDimensions, elementDimensions) {
232
+ if (align === 'end') {
233
+ return currentPos.left < containerDimensions.left;
234
+ }
235
+ else if (align === 'start' || align === 'center') {
236
+ return currentPos.left + elementDimensions.width > containerDimensions.left + containerDimensions.width;
237
+ }
238
+ }
@@ -11,5 +11,6 @@ export interface AnchorPosition {
11
11
  top: number;
12
12
  left: number;
13
13
  anchorSide: AnchorSide;
14
+ anchorAlign: AnchorAlignment;
14
15
  }
15
16
  export declare function getAnchoredPosition(floatingElement: Element, anchorElement: Element | DOMRect, settings?: Partial<PositionSettings>): AnchorPosition;
@@ -4,6 +4,11 @@ const alternateOrders = {
4
4
  'outside-left': ['outside-right', 'outside-bottom', 'outside-top', 'outside-bottom'],
5
5
  'outside-right': ['outside-left', 'outside-bottom', 'outside-top', 'outside-bottom']
6
6
  };
7
+ const alternateAlignments = {
8
+ start: ['end', 'center'],
9
+ end: ['start', 'center'],
10
+ center: ['end', 'start']
11
+ };
7
12
  export function getAnchoredPosition(floatingElement, anchorElement, settings = {}) {
8
13
  const parentElement = getPositionedParent(floatingElement);
9
14
  const clippingRect = getClippingRect(parentElement);
@@ -82,6 +87,7 @@ function pureCalculateAnchoredPosition(viewportRect, relativePosition, floatingR
82
87
  };
83
88
  let pos = calculatePosition(floatingRect, anchorRect, side, align, anchorOffset, alignmentOffset);
84
89
  let anchorSide = side;
90
+ let anchorAlign = align;
85
91
  pos.top -= relativePosition.top;
86
92
  pos.left -= relativePosition.left;
87
93
  if (!allowOutOfBounds) {
@@ -99,6 +105,20 @@ function pureCalculateAnchoredPosition(viewportRect, relativePosition, floatingR
99
105
  anchorSide = nextSide;
100
106
  }
101
107
  }
108
+ const alternateAlignment = alternateAlignments[align];
109
+ let alignmentAttempt = 0;
110
+ if (alternateAlignment) {
111
+ let prevAlign = align;
112
+ while (alignmentAttempt < alternateAlignment.length &&
113
+ shouldRecalculateAlignment(prevAlign, pos, relativeViewportRect, floatingRect)) {
114
+ const nextAlign = alternateAlignment[alignmentAttempt++];
115
+ prevAlign = nextAlign;
116
+ pos = calculatePosition(floatingRect, anchorRect, anchorSide, nextAlign, anchorOffset, alignmentOffset);
117
+ pos.top -= relativePosition.top;
118
+ pos.left -= relativePosition.left;
119
+ anchorAlign = nextAlign;
120
+ }
121
+ }
102
122
  if (pos.top < relativeViewportRect.top) {
103
123
  pos.top = relativeViewportRect.top;
104
124
  }
@@ -114,7 +134,7 @@ function pureCalculateAnchoredPosition(viewportRect, relativePosition, floatingR
114
134
  }
115
135
  }
116
136
  }
117
- return Object.assign(Object.assign({}, pos), { anchorSide });
137
+ return Object.assign(Object.assign({}, pos), { anchorSide, anchorAlign });
118
138
  }
119
139
  function calculatePosition(elementDimensions, anchorPosition, side, align, anchorOffset, alignmentOffset) {
120
140
  const anchorRight = anchorPosition.left + anchorPosition.width;
@@ -204,3 +224,11 @@ function shouldRecalculatePosition(side, currentPos, containerDimensions, elemen
204
224
  currentPos.left + elementDimensions.width > containerDimensions.width + containerDimensions.left);
205
225
  }
206
226
  }
227
+ function shouldRecalculateAlignment(align, currentPos, containerDimensions, elementDimensions) {
228
+ if (align === 'end') {
229
+ return currentPos.left < containerDimensions.left;
230
+ }
231
+ else if (align === 'start' || align === 'center') {
232
+ return currentPos.left + elementDimensions.width > containerDimensions.left + containerDimensions.width;
233
+ }
234
+ }
package/package.json CHANGED
@@ -1,22 +1,24 @@
1
1
  {
2
2
  "name": "@primer/behaviors",
3
- "version": "1.1.0",
3
+ "version": "1.1.2-rc.83d1cfb",
4
4
  "description": "Shared behaviors for JavaScript components",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "exports": {
8
8
  ".": {
9
- "types": "./dist/index.d.ts",
9
+ "module": "./dist/esm/index.js",
10
+ "import": "./dist/esm/index.js",
10
11
  "require": "./dist/cjs/index.js",
11
- "module": "./dist/esm/index.js"
12
+ "types": "./dist/esm/index.d.ts"
12
13
  },
13
14
  "./utils": {
14
- "types": "./dist/utils/index.d.ts",
15
+ "module": "./dist/esm/utils/index.js",
16
+ "import": "./dist/esm/utils/index.js",
15
17
  "require": "./dist/cjs/utils/index.js",
16
- "module": "./dist/esm/utils/index.js"
18
+ "types": "./dist/esm/utils/index.d.ts"
17
19
  }
18
20
  },
19
- "types": "dist/cjs/index.d.ts",
21
+ "types": "dist/esm/index.d.ts",
20
22
  "files": [
21
23
  "dist",
22
24
  "utils"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@primer/behaviors/utils",
3
3
  "types": "../dist/esm/utils/index.d.ts",
4
- "main": "../dist/esm/utils/index.js",
5
- "type": "module",
4
+ "main": "../dist/cjs/utils/index.js",
5
+ "module": "../dist/esm/utils/index.js",
6
6
  "sideEffects": false
7
7
  }