@brightspace-ui/core 3.142.2 → 3.143.0

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.
@@ -38,7 +38,7 @@
38
38
  <div style="border: 1px solid black; width: 600px;">stuff</div>
39
39
  <div slot="footer">footer content</div>
40
40
  </d2l-test-popover>
41
- <script>
41
+ <script data-demo-hide>
42
42
  window.wireUpPopover(document.currentScript.parentNode);
43
43
  </script>
44
44
  </template>
@@ -51,7 +51,7 @@
51
51
  <d2l-test-popover>
52
52
  <div>1</div>
53
53
  </d2l-test-popover>
54
- <script>
54
+ <script data-demo-hide>
55
55
  window.wireUpPopover(document.currentScript.parentNode);
56
56
  </script>
57
57
  </template>
@@ -64,7 +64,7 @@
64
64
  <d2l-test-popover>
65
65
  <div>Sink me piracy Gold Road.</div>
66
66
  </d2l-test-popover>
67
- <script>
67
+ <script data-demo-hide>
68
68
  window.wireUpPopover(document.currentScript.parentNode);
69
69
  </script>
70
70
  </template>
@@ -77,7 +77,7 @@
77
77
  <d2l-test-popover>
78
78
  <div>Sink me piracy Gold Road quarterdeck wherry long boat line pillage walk the plank Plate Fleet. Haul wind black spot strike colors deadlights lee Barbary Coast yo-ho-ho ballast gally Shiver me timbers. Sea Legs quarterdeck yard scourge of the seven seas coffer plunder lanyard holystone code of conduct belay.</div>
79
79
  </d2l-test-popover>
80
- <script>
80
+ <script data-demo-hide>
81
81
  window.wireUpPopover(document.currentScript.parentNode);
82
82
  </script>
83
83
  </template>
@@ -90,7 +90,7 @@
90
90
  <d2l-test-popover no-pointer>
91
91
  <div>Sink me piracy Gold Road quarterdeck wherry long boat line pillage walk the plank Plate Fleet. Haul wind black spot strike colors deadlights lee Barbary Coast yo-ho-ho ballast gally Shiver me timbers. Sea Legs quarterdeck yard scourge of the seven seas coffer plunder lanyard holystone code of conduct belay.</div>
92
92
  </d2l-test-popover>
93
- <script>
93
+ <script data-demo-hide>
94
94
  window.wireUpPopover(document.currentScript.parentNode);
95
95
  </script>
96
96
  </template>
@@ -103,7 +103,7 @@
103
103
  <d2l-test-popover max-width="1000">
104
104
  <div>Sink me piracy Gold Road quarterdeck wherry and some.</div>
105
105
  </d2l-test-popover>
106
- <script>
106
+ <script data-demo-hide>
107
107
  window.wireUpPopover(document.currentScript.parentNode);
108
108
  </script>
109
109
  </template>
@@ -116,7 +116,7 @@
116
116
  <d2l-test-popover max-width="1000">
117
117
  <div>Sink me piracy Gold Road quarterdeck wherry long boat line pillage walk the plank Plate Fleet. Haul wind black spot strike colors deadlights lee Barbary Coast yo-ho-ho ballast gally Shiver me timbers. Sea Legs quarterdeck yard scourge of the seven seas coffer plunder lanyard holystone code of conduct belay.</div>
118
118
  </d2l-test-popover>
119
- <script>
119
+ <script data-demo-hide>
120
120
  window.wireUpPopover(document.currentScript.parentNode);
121
121
  </script>
122
122
  </template>
@@ -129,7 +129,7 @@
129
129
  <d2l-test-popover min-width="60">
130
130
  <div>1</div>
131
131
  </d2l-test-popover>
132
- <script>
132
+ <script data-demo-hide>
133
133
  window.wireUpPopover(document.currentScript.parentNode);
134
134
  </script>
135
135
  </template>
@@ -138,25 +138,34 @@
138
138
  <h2>Popover (position location)</h2>
139
139
  <d2l-demo-snippet>
140
140
  <template>
141
- <d2l-button-subtle text="Open"></d2l-button-subtle>
142
- <d2l-test-popover position-location="block-start">
143
- <div>Sink me piracy Gold Road.</div>
144
- </d2l-test-popover>
145
- <script>
146
- window.wireUpPopover(document.currentScript.parentNode);
147
- </script>
148
- </template>
149
- </d2l-demo-snippet>
150
-
151
- <h2>Popover (position span)</h2>
152
- <d2l-demo-snippet>
153
- <template>
154
- <div style="text-align: center;"><d2l-button-subtle text="Open"></d2l-button-subtle></div>
155
- <d2l-test-popover position-span="end">
156
- <div>Sink me piracy Gold Road.</div>
157
- </d2l-test-popover>
158
- <script>
159
- window.wireUpPopover(document.currentScript.parentNode);
141
+ <div>
142
+ <select id="location">
143
+ <option value="block-start">block-start</option>
144
+ <option value="block-end" selected>block-end</option>
145
+ <option value="inline-start">inline-start</option>
146
+ <option value="inline-end">inline-end</option>
147
+ </select>
148
+ <select id="span">
149
+ <option value="all" selected>all</option>
150
+ <option value="start">start</option>
151
+ <option value="end">end</option>
152
+ </select>
153
+ </div>
154
+ <div style="text-align: center;">
155
+ <d2l-button-subtle text="Open"></d2l-button-subtle>
156
+ <d2l-test-popover position-location="block-end">
157
+ <div>Sink me piracy Gold Road.</div>
158
+ </d2l-test-popover>
159
+ </div>
160
+ <script data-demo-hide>
161
+ const demo = document.currentScript.parentNode;
162
+ window.wireUpPopover(demo);
163
+ demo.querySelector('#location').addEventListener('change', e => {
164
+ demo.querySelector('d2l-test-popover').positionLocation = e.target.value;
165
+ });
166
+ demo.querySelector('#span').addEventListener('change', e => {
167
+ demo.querySelector('d2l-test-popover').positionSpan = e.target.value;
168
+ });
160
169
  </script>
161
170
  </template>
162
171
  </d2l-demo-snippet>
@@ -174,7 +183,7 @@
174
183
  <p>Trysail Sail ho Corsair red ensign hulk smartly boom jib rum gangway. Case shot Shiver me timbers gangplank crack Jennys tea cup ballast Blimey lee snow crow's nest rutters. Fluke jib scourge of the seven seas boatswain schooner gaff booty Jack Tar transom spirits.</p>
175
184
  <p>Hardtack hang the jib haul wind booty pillage spike hearties Pirate Round tack yard. Piracy fire ship trysail stern scurvy blow the man down skysail salmagundi lee grog blossom. Hands gabion ho schooner lad ballast keel mutiny square-rigged haul wind.</p>
176
185
  </div>
177
- <script>
186
+ <script data-demo-hide>
178
187
  window.wireUpPopover(document.currentScript.parentNode);
179
188
  </script>
180
189
  </template>
@@ -190,7 +199,7 @@
190
199
  <d2l-button-subtle id="mutations-add-above">Add to Above</d2l-button-subtle>
191
200
  </d2l-test-popover>
192
201
  </div>
193
- <script>
202
+ <script data-demo-hide>
194
203
  window.wireUpPopover(document.currentScript.parentNode);
195
204
 
196
205
  document.querySelector('#mutations-add-above').addEventListener('click', e => {
@@ -221,7 +230,7 @@
221
230
  <d2l-button slot="footer" primary data-dialog-action="ok">Click Me!</d2l-button>
222
231
  <d2l-button slot="footer" data-dialog-action>Cancel</d2l-button>
223
232
  </d2l-dialog>
224
- <script>
233
+ <script data-demo-hide>
225
234
  document.querySelector('#openDialog1').addEventListener('click', () => {
226
235
  document.querySelector('#dialog1').opened = true;
227
236
  });
@@ -243,7 +252,7 @@
243
252
  <div>Piracy bowsprit Arr shrouds salmagundi scuttle heave down doubloon trysail Jack Ketch. Killick boom Jolly Roger Pieces of Eight crack Jennys tea cup Cat o'nine tails league Privateer topgallant lanyard. Cat o'nine tails coxswain scurvy spirits keelhaul quarterdeck matey nipper scallywag Jolly Roger.</div>
244
253
  </d2l-test-popover>
245
254
  </d2l-test-popover>
246
- <script>
255
+ <script data-demo-hide>
247
256
  document.querySelector('#outerOpener').addEventListener('click', () => {
248
257
  const popover = document.querySelector('#outerPopover');
249
258
  popover.opened = !popover.opened;
@@ -266,7 +275,7 @@
266
275
  <div>Sink me piracy Gold Road quarterdeck wherry long boat line pillage walk the plank Plate Fleet. Haul wind black spot strike colors deadlights lee Barbary Coast yo-ho-ho ballast gally Shiver me timbers. Sea Legs quarterdeck yard scourge of the seven seas coffer plunder lanyard holystone code of conduct belay.</div>
267
276
  <d2l-button-subtle text="Close"></d2l-button-subtle>
268
277
  </d2l-test-popover>
269
- <script>
278
+ <script data-demo-hide>
270
279
  window.wireUpPopover(document.currentScript.parentNode);
271
280
  </script>
272
281
  </template>
@@ -281,7 +290,7 @@
281
290
  <d2l-link href="https://pirateipsum.me/" target="_blank">Pirate Ipsum</d2l-link>
282
291
  <div>Sink me piracy Gold Road quarterdeck wherry long boat line pillage walk the plank Plate Fleet. Haul wind black spot strike colors deadlights lee Barbary Coast yo-ho-ho ballast gally Shiver me timbers. Sea Legs quarterdeck yard scourge of the seven seas coffer plunder lanyard holystone code of conduct belay.</div>
283
292
  </d2l-test-popover>
284
- <script>
293
+ <script data-demo-hide>
285
294
  window.wireUpPopover(document.currentScript.parentNode);
286
295
  </script>
287
296
  </template>
@@ -6,12 +6,25 @@ import { css, html, nothing } from 'lit';
6
6
  import { getComposedActiveElement, getFirstFocusableDescendant, getPreviousFocusableAncestor } from '../../helpers/focus.js';
7
7
  import { getComposedParent, isComposedAncestor } from '../../helpers/dom.js';
8
8
  import { _offscreenStyleDeclarations } from '../offscreen/offscreen.js';
9
+ import { classMap } from 'lit/directives/class-map.js';
9
10
  import { styleMap } from 'lit/directives/style-map.js';
10
11
  import { tryGetIfrauBackdropService } from '../../helpers/ifrauBackdropService.js';
11
12
 
13
+ export const positionLocations = Object.freeze({
14
+ blockEnd: 'block-end',
15
+ blockStart: 'block-start',
16
+ inlineEnd: 'inline-end',
17
+ inlineStart: 'inline-start'
18
+ });
19
+ export const positionSpans = Object.freeze({
20
+ all: 'all',
21
+ end: 'end',
22
+ start: 'start'
23
+ });
24
+
12
25
  const defaultPreferredPosition = {
13
- location: 'block-end', // block-start, block-end
14
- span: 'all', // start, end, all
26
+ location: positionLocations.blockEnd,
27
+ span: positionSpans.all,
15
28
  allowFlip: true
16
29
  };
17
30
  const minBackdropHeightMobile = 42;
@@ -20,6 +33,12 @@ const pointerLength = 16;
20
33
  const pointerRotatedLength = Math.SQRT2 * parseFloat(pointerLength);
21
34
  const isSupported = ('popover' in HTMLElement.prototype);
22
35
 
36
+ const getScrollbarWidth = () => {
37
+ const width = window.innerWidth - document.documentElement.clientWidth;
38
+ if (width > 0) return width + 1; // 16 when present, but can be 0 even if visible (ex. MacOS depending on settings)
39
+ else return 0;
40
+ };
41
+
23
42
  export const PopoverMixin = superclass => class extends superclass {
24
43
 
25
44
  static get properties() {
@@ -127,6 +146,17 @@ export const PopoverMixin = superclass => class extends superclass {
127
146
  position: absolute;
128
147
  z-index: 1;
129
148
  }
149
+ :host([_location="block-start"]) .pointer {
150
+ clip: rect(9px, 21px, 22px, -3px);
151
+ }
152
+ :host([_location="inline-start"]) .pointer,
153
+ :host([_location="inline-end"]) .pointer.pointer-mirror {
154
+ clip: rect(-3px, 21px, 21px, 10px);
155
+ }
156
+ :host([_location="inline-end"]) .pointer,
157
+ :host([_location="inline-start"]) .pointer.pointer-mirror {
158
+ clip: rect(-3px, 8px, 21px, -3px);
159
+ }
130
160
 
131
161
  .pointer > div {
132
162
  background-color: var(--d2l-popover-background-color, var(--d2l-popover-default-background-color));
@@ -138,10 +168,6 @@ export const PopoverMixin = superclass => class extends superclass {
138
168
  width: ${pointerLength}px;
139
169
  }
140
170
 
141
- :host([_location="block-start"]) .pointer {
142
- clip: rect(9px, 21px, 22px, -3px);
143
- }
144
-
145
171
  :host([_location="block-start"]) .pointer > div {
146
172
  box-shadow: 4px 4px 12px -5px rgba(32, 33, 34, 0.2); /* ferrite */
147
173
  }
@@ -278,7 +304,10 @@ export const PopoverMixin = superclass => class extends superclass {
278
304
  }
279
305
 
280
306
  configure(properties) {
281
- this._margin = properties?.margin ?? 18;
307
+ if (properties?.margin) this._margin = properties.margin;
308
+ else if (properties?.position?.location === positionLocations.inlineStart
309
+ || properties?.position?.location === positionLocations.inlineEnd) this._margin = 0;
310
+ else this._margin = 18;
282
311
  this._maxHeight = properties?.maxHeight;
283
312
  this._maxWidth = properties?.maxWidth;
284
313
  this._minHeight = properties?.minHeight;
@@ -296,8 +325,8 @@ export const PopoverMixin = superclass => class extends superclass {
296
325
  || this._preferredPosition?.span !== properties.position?.span
297
326
  || this._preferredPosition?.allowFlip !== properties.position?.allowFlip) {
298
327
  this._preferredPosition = {
299
- location: properties?.position?.location ?? 'block-end',
300
- span: properties?.position?.span ?? 'all',
328
+ location: properties?.position?.location ?? positionLocations.blockEnd,
329
+ span: properties?.position?.span ?? positionSpans.all,
301
330
  allowFlip: properties?.position?.allowFlip ?? true
302
331
  };
303
332
  }
@@ -371,11 +400,12 @@ export const PopoverMixin = superclass => class extends superclass {
371
400
  };
372
401
 
373
402
  // space in viewport
403
+ const prefersInline = this._preferredPosition.location === positionLocations.inlineStart || this._preferredPosition.location === positionLocations.inlineEnd;
374
404
  const spaceAround = this.#constrainSpaceAround({
375
405
  // allow for opener offset + outer margin
376
- above: openerRect.top - this._offset - this._margin,
406
+ above: openerRect.top - (prefersInline ? 0 : this._offset) - this._margin,
377
407
  // allow for opener offset + outer margin
378
- below: window.innerHeight - openerRect.bottom - this._offset - this._margin,
408
+ below: window.innerHeight - openerRect.bottom - (prefersInline ? 0 : this._offset) - this._margin,
379
409
  // allow for outer margin
380
410
  left: openerRect.left - 20,
381
411
  // allow for outer margin
@@ -398,7 +428,9 @@ export const PopoverMixin = superclass => class extends superclass {
398
428
  if (options.updateHeight) {
399
429
 
400
430
  // calculate height available to the popover contents for overflow because that is the only area capable of scrolling
401
- const availableHeight = (this._location === 'block-start') ? spaceAround.above : spaceAround.below;
431
+ const availableHeight = (this._location === positionLocations.inlineStart || this._location === positionLocations.inlineEnd)
432
+ ? (spaceAround.above + spaceAround.below + openerRect.height)
433
+ : (this._location === positionLocations.blockStart ? spaceAround.above : spaceAround.below);
402
434
 
403
435
  if (!this._noAutoFit && availableHeight && availableHeight > 0) {
404
436
  // only apply maximum if it's less than space available and the header/footer alone won't exceed it (content must be visible)
@@ -409,8 +441,6 @@ export const PopoverMixin = superclass => class extends superclass {
409
441
  await this.updateComplete;
410
442
  }
411
443
 
412
- // todo: handle inline-start and inline-end locations
413
-
414
444
  }
415
445
 
416
446
  /** @ignore */
@@ -434,9 +464,9 @@ export const PopoverMixin = superclass => class extends superclass {
434
464
  const mobileTrayLocation = this._mobile ? this._mobileTrayLocation : null;
435
465
 
436
466
  let stylesMap;
437
- if (mobileTrayLocation === 'block-end') {
467
+ if (mobileTrayLocation === positionLocations.blockEnd) {
438
468
  stylesMap = this.#getMobileTrayBlockStyleMaps();
439
- } else if (mobileTrayLocation === 'inline-start' || mobileTrayLocation === 'inline-end') {
469
+ } else if (mobileTrayLocation === positionLocations.inlineStart || mobileTrayLocation === positionLocations.inlineEnd) {
440
470
  stylesMap = this.#getMobileTrayInlineStyleMaps();
441
471
  } else {
442
472
  stylesMap = this.#getStyleMaps();
@@ -478,8 +508,12 @@ export const PopoverMixin = superclass => class extends superclass {
478
508
  }
479
509
  }
480
510
 
511
+ const pointerClasses = {
512
+ 'pointer': true,
513
+ 'pointer-mirror': this._rtl
514
+ };
481
515
  const pointer = !this._noPointer ? html`
482
- <div class="pointer" style="${styleMap(pointerPositionStyles)}">
516
+ <div class="${classMap(pointerClasses)}" style="${styleMap(pointerPositionStyles)}">
483
517
  <div></div>
484
518
  </div>
485
519
  ` : nothing;
@@ -580,9 +614,9 @@ export const PopoverMixin = superclass => class extends superclass {
580
614
  #constrainSpaceAround(spaceAround, spaceRequired, openerRect) {
581
615
  const constrained = { ...spaceAround };
582
616
 
583
- if ((this._preferredPosition.span === 'end' && !this._rtl) || (this._preferredPosition.span === 'start' && this._rtl)) {
617
+ if ((this._preferredPosition.span === positionSpans.end && !this._rtl) || (this._preferredPosition.span === positionSpans.start && this._rtl)) {
584
618
  constrained.left = Math.max(0, spaceRequired.width - (openerRect.width + spaceAround.right));
585
- } else if ((this._preferredPosition.span === 'end' && this._rtl) || (this._preferredPosition.span === 'start' && !this._rtl)) {
619
+ } else if ((this._preferredPosition.span === positionSpans.end && this._rtl) || (this._preferredPosition.span === positionSpans.start && !this._rtl)) {
586
620
  constrained.right = Math.max(0, spaceRequired.width - (openerRect.width + spaceAround.left));
587
621
  }
588
622
 
@@ -621,28 +655,46 @@ export const PopoverMixin = superclass => class extends superclass {
621
655
  return preferred.location;
622
656
  }
623
657
 
624
- if (preferred.location === 'block-end') {
625
- if (spaceAround.below >= spaceRequired.height) return 'block-end';
626
- if (spaceAround.above >= spaceRequired.height) return 'block-start';
658
+ if (preferred.location === positionLocations.blockEnd) {
659
+ if (spaceAround.below >= spaceRequired.height) return positionLocations.blockEnd;
660
+ if (spaceAround.above >= spaceRequired.height) return positionLocations.blockStart;
627
661
  // if auto-fit is enabled, scroll will be enabled for the inner content so it will always fit in the available space so pick the largest space it can be displayed in
628
- if (!this.noAutoFit) return spaceAround.above > spaceAround.below ? 'block-start' : 'block-end';
629
- if (spaceAroundScroll.below >= spaceRequired.height) return 'block-end';
630
- if (spaceAroundScroll.above >= spaceRequired.height) return 'block-start';
662
+ if (!this.noAutoFit) return spaceAround.above > spaceAround.below ? positionLocations.blockStart : positionLocations.blockEnd;
663
+ if (spaceAroundScroll.below >= spaceRequired.height) return positionLocations.blockEnd;
664
+ if (spaceAroundScroll.above >= spaceRequired.height) return positionLocations.blockStart;
631
665
  }
632
666
 
633
- if (preferred.location === 'block-start') {
634
- if (spaceAround.above >= spaceRequired.height) return 'block-start';
635
- if (spaceAround.below >= spaceRequired.height) return 'block-end';
667
+ if (preferred.location === positionLocations.blockStart) {
668
+ if (spaceAround.above >= spaceRequired.height) return positionLocations.blockStart;
669
+ if (spaceAround.below >= spaceRequired.height) return positionLocations.blockEnd;
636
670
  // if auto-fit is enabled, scroll will be enabled for the inner content so it will always fit in the available space so pick the largest space it can be displayed in
637
- if (!this.noAutoFit) return spaceAround.above > spaceAround.below ? 'block-start' : 'block-end';
638
- if (spaceAroundScroll.above >= spaceRequired.height) return 'block-start';
639
- if (spaceAroundScroll.below >= spaceRequired.height) return 'block-end';
671
+ if (!this.noAutoFit) return spaceAround.above > spaceAround.below ? positionLocations.blockStart : positionLocations.blockEnd;
672
+ if (spaceAroundScroll.above >= spaceRequired.height) return positionLocations.blockStart;
673
+ if (spaceAroundScroll.below >= spaceRequired.height) return positionLocations.blockEnd;
640
674
  }
641
675
 
642
- // todo: add location order for inline-start and inline-end
676
+ if (preferred.location === positionLocations.inlineEnd) {
677
+ if (this._rtl) {
678
+ if (spaceAround.left >= spaceRequired.width) return positionLocations.inlineEnd;
679
+ if (spaceAround.right >= spaceRequired.width) return positionLocations.inlineStart;
680
+ } else {
681
+ if (spaceAround.right >= spaceRequired.width) return positionLocations.inlineEnd;
682
+ if (spaceAround.left >= spaceRequired.width) return positionLocations.inlineStart;
683
+ }
684
+ }
685
+
686
+ if (preferred.location === positionLocations.inlineStart) {
687
+ if (this._rtl) {
688
+ if (spaceAround.right >= spaceRequired.width) return positionLocations.inlineStart;
689
+ if (spaceAround.left >= spaceRequired.width) return positionLocations.inlineEnd;
690
+ } else {
691
+ if (spaceAround.left >= spaceRequired.width) return positionLocations.inlineStart;
692
+ if (spaceAround.right >= spaceRequired.width) return positionLocations.inlineEnd;
693
+ }
694
+ }
643
695
 
644
696
  // if auto-fit is disabled and it doesn't fit in the scrollable space above or below, always open down because it can add scrollable space
645
- return 'block-end';
697
+ return positionLocations.blockEnd;
646
698
  }
647
699
 
648
700
  #getMobileTrayBlockStyleMaps() {
@@ -743,11 +795,11 @@ export const PopoverMixin = superclass => class extends superclass {
743
795
 
744
796
  let inlineEndOverride;
745
797
  let inlineStartOverride;
746
- if (this._mobileTrayLocation === 'inline-end') {
798
+ if (this._mobileTrayLocation === positionLocations.inlineEnd) {
747
799
  // On non-responsive pages, the innerWidth may be wider than the screen,
748
800
  // override right to stick to right of viewport
749
801
  inlineEndOverride = `${Math.max(window.innerWidth - window.screen.width, 0)}px`;
750
- } else if (this._mobileTrayLocation === 'inline-start') {
802
+ } else if (this._mobileTrayLocation === positionLocations.inlineStart) {
751
803
  // On non-responsive pages, the innerWidth may be wider than the screen,
752
804
  // override left to stick to left of viewport
753
805
  inlineStartOverride = `${Math.max(window.innerWidth - window.screen.width, 0)}px`;
@@ -794,33 +846,55 @@ export const PopoverMixin = superclass => class extends superclass {
794
846
 
795
847
  const pointerRect = pointer.getBoundingClientRect();
796
848
 
797
- if (this._preferredPosition.span !== 'all') {
798
- const xAdjustment = Math.min(20 + ((pointerRotatedLength - pointerLength) / 2), (openerRect.width - pointerLength) / 2);
799
- if (!this._rtl) {
800
- if (this._preferredPosition.span === 'end') {
801
- position.left = openerRect.left + xAdjustment;
849
+ if (this._location === positionLocations.blockEnd || this._location === positionLocations.blockStart) {
850
+
851
+ if (this._preferredPosition.span !== positionSpans.all) {
852
+ const xAdjustment = Math.min(20 + ((pointerRotatedLength - pointerLength) / 2), (openerRect.width - pointerLength) / 2);
853
+ if (!this._rtl) {
854
+ if (this._preferredPosition.span === positionSpans.end) {
855
+ position.left = openerRect.left + xAdjustment;
856
+ } else {
857
+ position.right = (openerRect.right * -1) + xAdjustment;
858
+ }
802
859
  } else {
803
- position.right = (openerRect.right * -1) + xAdjustment;
860
+ if (this._preferredPosition.span === positionSpans.end) {
861
+ position.right = window.innerWidth - openerRect.right + xAdjustment - getScrollbarWidth();
862
+ } else {
863
+ position.left = (window.innerWidth - openerRect.left - xAdjustment - getScrollbarWidth()) * -1;
864
+ }
804
865
  }
805
866
  } else {
806
- if (this._preferredPosition.span === 'end') {
807
- position.right = window.innerWidth - openerRect.right + xAdjustment;
867
+ if (!this._rtl) {
868
+ position.left = openerRect.left + ((openerRect.width - pointerRect.width) / 2);
808
869
  } else {
809
- position.left = (window.innerWidth - openerRect.left - xAdjustment) * -1;
870
+ position.right = window.innerWidth - openerRect.left - ((openerRect.width + pointerRect.width) / 2) - getScrollbarWidth();
810
871
  }
811
872
  }
812
- } else {
813
- if (!this._rtl) {
814
- position.left = openerRect.left + ((openerRect.width - pointerRect.width) / 2);
873
+
874
+ if (this._location === positionLocations.blockStart) {
875
+ position.bottom = window.innerHeight - openerRect.top + this._offset - 8; // 8 minor adjustment to position pointer at edge of content
815
876
  } else {
816
- position.right = window.innerWidth - openerRect.left - ((openerRect.width + pointerRect.width) / 2);
877
+ position.top = openerRect.top + openerRect.height + this._offset - 7; // 7 minor adjustment to position pointer at edge of content
878
+ }
879
+
880
+ } else if (this._location === positionLocations.inlineEnd || this._location === positionLocations.inlineStart) {
881
+
882
+ position.top = openerRect.top + (openerRect.height / 2) - (pointerLength / 2);
883
+
884
+ if (this._location === positionLocations.inlineStart) {
885
+ if (!this._rtl) {
886
+ position.right = (openerRect.left - this._offset + 7) * -1; // 7 minor adjustment to position pointer at edge of content
887
+ } else {
888
+ position.left = (window.innerWidth - openerRect.right + 7 - this._offset - getScrollbarWidth()) * -1; // 7 minor adjustment to position pointer at edge of content
889
+ }
890
+ } else {
891
+ if (!this._rtl) {
892
+ position.left = openerRect.left + openerRect.width + this._offset - 7; // 7 minor adjustment to position pointer at edge of content
893
+ } else {
894
+ position.right = window.innerWidth - openerRect.left - 7 + this._offset - getScrollbarWidth(); // 7 minor adjustment to position pointer at edge of content
895
+ }
817
896
  }
818
- }
819
897
 
820
- if (this._location === 'block-start') {
821
- position.bottom = window.innerHeight - openerRect.top + this._offset - 8;
822
- } else {
823
- position.top = openerRect.top + openerRect.height + this._offset - 7;
824
898
  }
825
899
 
826
900
  return position;
@@ -829,79 +903,124 @@ export const PopoverMixin = superclass => class extends superclass {
829
903
  #getPosition(spaceAround, openerRect, contentRect) {
830
904
  const position = {};
831
905
 
832
- if (this._location === 'block-end' || this._location === 'block-start') {
906
+ if (this._location === positionLocations.blockEnd || this._location === positionLocations.blockStart) {
833
907
 
834
908
  const xAdjustment = this.#getPositionXAdjustment(spaceAround, openerRect, contentRect);
835
909
  if (xAdjustment !== null) {
836
910
  if (!this._rtl) {
837
911
  position.left = openerRect.left + xAdjustment;
838
912
  } else {
839
- position.right = window.innerWidth - openerRect.left - openerRect.width + xAdjustment;
913
+ position.right = window.innerWidth - openerRect.left - openerRect.width + xAdjustment - getScrollbarWidth();
840
914
  }
841
915
  }
842
916
 
843
- if (this._location === 'block-start') {
917
+ if (this._location === positionLocations.blockStart) {
844
918
  position.bottom = window.innerHeight - openerRect.top + this._offset;
845
919
  } else {
846
920
  position.top = openerRect.top + openerRect.height + this._offset;
847
921
  }
848
922
 
849
- }
923
+ } else if (this._location === positionLocations.inlineEnd || this._location === positionLocations.inlineStart) {
850
924
 
851
- // todo: add position styles for inline-start and inline-end
925
+ const yAdjustment = this.#getPositionYAdjustment(spaceAround, openerRect, contentRect);
926
+ if (yAdjustment !== null) {
927
+ position.top = openerRect.top + yAdjustment;
928
+ }
929
+
930
+ if (this._location === positionLocations.inlineStart) {
931
+ if (!this._rtl) {
932
+ position.right = (openerRect.left - this._offset) * -1;
933
+ } else {
934
+ position.left = (window.innerWidth - openerRect.right - this._offset - getScrollbarWidth()) * -1;
935
+ }
936
+ } else {
937
+ if (!this._rtl) {
938
+ position.left = openerRect.left + openerRect.width + this._offset;
939
+ } else {
940
+ position.right = window.innerWidth - openerRect.left + this._offset - getScrollbarWidth();
941
+ }
942
+ }
943
+
944
+ }
852
945
 
853
946
  return position;
854
947
  }
855
948
 
856
949
  #getPositionXAdjustment(spaceAround, openerRect, contentRect) {
857
950
 
858
- if (this._location === 'block-end' || this._location === 'block-start') {
951
+ if (this._location !== positionLocations.blockEnd && this._location !== positionLocations.blockStart) return null;
952
+
953
+ const centerDelta = contentRect.width - openerRect.width;
954
+ const contentXAdjustment = centerDelta / 2;
859
955
 
860
- const centerDelta = contentRect.width - openerRect.width;
861
- const contentXAdjustment = centerDelta / 2;
956
+ if (this._preferredPosition.span === positionSpans.all && centerDelta <= 0) {
957
+ // center with target (opener wider than content)
958
+ return contentXAdjustment * -1;
959
+ }
960
+ if (this._preferredPosition.span === positionSpans.all && spaceAround.left > contentXAdjustment && spaceAround.right > contentXAdjustment) {
961
+ // center with target (content wider than opener and enough space around)
962
+ return contentXAdjustment * -1;
963
+ }
862
964
 
863
- if (this._preferredPosition.span === 'all' && centerDelta <= 0) {
864
- // center with target (opener wider than content)
865
- return contentXAdjustment * -1;
965
+ if (!this._rtl) {
966
+ if (spaceAround.left < contentXAdjustment) {
967
+ // slide content right (not enough space to center)
968
+ return spaceAround.left * -1;
969
+ } else if (spaceAround.right < contentXAdjustment) {
970
+ // slide content left (not enough space to center)
971
+ return (centerDelta * -1) + spaceAround.right;
866
972
  }
867
- if (this._preferredPosition.span === 'all' && spaceAround.left > contentXAdjustment && spaceAround.right > contentXAdjustment) {
868
- // center with target (content wider than opener and enough space around)
869
- return contentXAdjustment * -1;
973
+ } else {
974
+ if (spaceAround.left < contentXAdjustment) {
975
+ // slide content right (not enough space to center)
976
+ return (centerDelta * -1) + spaceAround.left;
977
+ } else if (spaceAround.right < contentXAdjustment) {
978
+ // slide content left (not enough space to center)
979
+ return spaceAround.right * -1;
870
980
  }
981
+ }
871
982
 
872
- if (!this._rtl) {
873
- if (spaceAround.left < contentXAdjustment) {
874
- // slide content right (not enough space to center)
875
- return spaceAround.left * -1;
876
- } else if (spaceAround.right < contentXAdjustment) {
877
- // slide content left (not enough space to center)
878
- return (centerDelta * -1) + spaceAround.right;
879
- }
983
+ if (this._preferredPosition.span !== positionSpans.all) {
984
+ // shift it (not enough space to align as requested)
985
+ const shift = Math.min((openerRect.width / 2) - (20 + pointerLength / 2), 0); // 20 ~= 1rem
986
+ if (this._preferredPosition.span === positionSpans.end) {
987
+ return shift;
880
988
  } else {
881
- if (spaceAround.left < contentXAdjustment) {
882
- // slide content right (not enough space to center)
883
- return (centerDelta * -1) + spaceAround.left;
884
- } else if (spaceAround.right < contentXAdjustment) {
885
- // slide content left (not enough space to center)
886
- return spaceAround.right * -1;
887
- }
989
+ return openerRect.width - contentRect.width - shift;
888
990
  }
991
+ }
889
992
 
890
- if (this._preferredPosition.span !== 'all') {
891
- // shift it (not enough space to align as requested)
892
- const shift = Math.min((openerRect.width / 2) - (20 + pointerLength / 2), 0); // 20 ~= 1rem
893
- if (this._preferredPosition.span === 'end') {
894
- return shift;
895
- } else {
896
- return openerRect.width - contentRect.width - shift;
897
- }
898
- }
993
+ return null;
899
994
 
995
+ }
996
+
997
+ #getPositionYAdjustment(spaceAround, openerRect, contentRect) {
998
+
999
+ if (this._location !== positionLocations.inlineEnd && this._location !== positionLocations.inlineStart) return null;
1000
+
1001
+ const centerDelta = contentRect.height - openerRect.height;
1002
+ const contentYAdjustment = centerDelta / 2;
1003
+
1004
+ if (this._preferredPosition.span === positionSpans.all && centerDelta <= 0) {
1005
+ // center with target (opener taller than content)
1006
+ return contentYAdjustment * -1;
900
1007
  }
901
1008
 
902
- // todo: add position styles for inline-start and inline-end
1009
+ if (this._preferredPosition.span === positionSpans.all && spaceAround.above > contentYAdjustment && spaceAround.below > contentYAdjustment) {
1010
+ // center with target (content wider than opener and enough space around)
1011
+ return contentYAdjustment * -1;
1012
+ }
1013
+
1014
+ if (spaceAround.above < contentYAdjustment) {
1015
+ // slide content down (not enough space to center)
1016
+ return spaceAround.above * -1;
1017
+ } else if (spaceAround.below < contentYAdjustment) {
1018
+ // slide content up (not enough space to center)
1019
+ return (centerDelta * -1) + spaceAround.below;
1020
+ }
903
1021
 
904
1022
  return null;
1023
+
905
1024
  }
906
1025
 
907
1026
  #getStyleMaps() {
@@ -11519,6 +11519,11 @@
11519
11519
  "name": "d2l-test-popover",
11520
11520
  "path": "./components/popover/test/popover.js",
11521
11521
  "attributes": [
11522
+ {
11523
+ "name": "margin",
11524
+ "description": "Margin to include when computing space available.",
11525
+ "type": "number"
11526
+ },
11522
11527
  {
11523
11528
  "name": "max-height",
11524
11529
  "description": "Max-height. Note that the default behaviour is to be as tall as necessary within the viewport, so this property is usually not needed.",
@@ -11580,6 +11585,12 @@
11580
11585
  }
11581
11586
  ],
11582
11587
  "properties": [
11588
+ {
11589
+ "name": "margin",
11590
+ "attribute": "margin",
11591
+ "description": "Margin to include when computing space available.",
11592
+ "type": "number"
11593
+ },
11583
11594
  {
11584
11595
  "name": "maxHeight",
11585
11596
  "attribute": "max-height",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.142.2",
3
+ "version": "3.143.0",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",