mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
Drop hoist from public API, use Popover API where supported (#351)
* First stab at using the Popover API for PE * fix popup * First stab at using the Popover API for PE * fix popup * Prettier * Fix TS error * Remove workaround * Default to `strategy = fixed` if Popover API is not supported * Clear out default UA styles for popovers * Kill `hoist` with fire 🔥 * Refactor * Update `@floating-ui/dom` * Fix flipping and shofting * Fix autosize * Use `defaultBoundary` for `flip` too That way we get the previous behavior for it. * Remove `strategy`, just use `SUPPORTS_POPOVER` check where relevant * Remove uses of `strategy` * Use viewport as the default boundary for shifting and autosizing and add `boundary=scroll` to override --------- Co-authored-by: konnorrogers <konnor5456@gmail.com>
This commit is contained in:
@@ -126,7 +126,7 @@
|
||||
{% for h in hues -%}
|
||||
{%- if h !== 'gray' -%}
|
||||
<wa-radio-button id="gray-undertone-{{ h }}" value="{{ h }}" label="{{ h | capitalize }}" style="--color: var(--wa-color-{{ h }})"></wa-radio-button>
|
||||
<wa-tooltip for="gray-undertone-{{ h }}" hoist>
|
||||
<wa-tooltip for="gray-undertone-{{ h }}">
|
||||
{{ h | capitalize }}
|
||||
</wa-tooltip>
|
||||
{%- endif -%}
|
||||
|
||||
@@ -33,7 +33,7 @@ export function copyCodePlugin(eleventyConfig, options = {}) {
|
||||
|
||||
// Add a copy button
|
||||
pre.innerHTML += `<wa-icon-button href="#${preId}" class="block-link-icon" name="link"></wa-icon-button>
|
||||
<wa-copy-button from="${codeId}" class="copy-button" hoist></wa-copy-button>`;
|
||||
<wa-copy-button from="${codeId}" class="copy-button"></wa-copy-button>`;
|
||||
});
|
||||
|
||||
return doc.toString();
|
||||
|
||||
@@ -167,7 +167,7 @@ Other elements can also be placed inside button groups:
|
||||
<wa-button-group label="Example Button Group">
|
||||
<wa-button>Button</wa-button>
|
||||
<button>Native Button</button>
|
||||
<wa-dropdown hoist>
|
||||
<wa-dropdown>
|
||||
<wa-button slot="trigger" caret>Dropdown</wa-button>
|
||||
<wa-menu>
|
||||
<wa-menu-item>Item 1</wa-menu-item>
|
||||
@@ -185,7 +185,7 @@ Create a split button using a button and a dropdown. Use a [visually hidden](/do
|
||||
```html {.example}
|
||||
<wa-button-group label="Example Button Group">
|
||||
<wa-button variant="brand">Save</wa-button>
|
||||
<wa-dropdown placement="bottom-end" hoist>
|
||||
<wa-dropdown placement="bottom-end">
|
||||
<wa-button slot="trigger" variant="brand" caret>
|
||||
<span class="wa-visually-hidden">More options</span>
|
||||
</wa-button>
|
||||
|
||||
@@ -180,38 +180,3 @@ To create a submenu, nest an `<wa-menu slot="submenu">` element in a [menu item]
|
||||
:::warning
|
||||
As a UX best practice, avoid using more than one level of submenu when possible.
|
||||
:::
|
||||
|
||||
### Hoisting
|
||||
|
||||
Dropdown panels will be clipped if they're inside a container that has `overflow: auto|hidden`. The `hoist` attribute forces the panel to use a fixed positioning strategy, allowing it to break out of the container. In this case, the panel will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html {.example}
|
||||
<div class="dropdown-hoist">
|
||||
<wa-dropdown>
|
||||
<wa-button slot="trigger" caret>No Hoist</wa-button>
|
||||
<wa-menu>
|
||||
<wa-menu-item>Item 1</wa-menu-item>
|
||||
<wa-menu-item>Item 2</wa-menu-item>
|
||||
<wa-menu-item>Item 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
</wa-dropdown>
|
||||
|
||||
<wa-dropdown hoist>
|
||||
<wa-button slot="trigger" caret>Hoist</wa-button>
|
||||
<wa-menu>
|
||||
<wa-menu-item>Item 1</wa-menu-item>
|
||||
<wa-menu-item>Item 2</wa-menu-item>
|
||||
<wa-menu-item>Item 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
</wa-dropdown>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.dropdown-hoist {
|
||||
position: relative;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
padding: var(--wa-space-m);
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
@@ -468,68 +468,10 @@ Use the `sync` attribute to make the popup the same width or height as the ancho
|
||||
</script>
|
||||
```
|
||||
|
||||
### Positioning Strategy
|
||||
|
||||
By default, the popup is positioned using an absolute positioning strategy. However, if your anchor is fixed or exists within a container that has `overflow: auto|hidden`, the popup risks being clipped. To work around this, you can use a fixed positioning strategy by setting the `strategy` attribute to `fixed`.
|
||||
|
||||
The fixed positioning strategy reduces jumpiness when the anchor is fixed and allows the popup to break out containers that clip. When using this strategy, it's important to note that the content will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
In this example, you can see how the popup breaks out of the overflow container when it's fixed. The fixed positioning strategy tends to be less performant than absolute, so avoid using it unnecessarily.
|
||||
|
||||
Toggle the switch and scroll the container to see the difference.
|
||||
|
||||
```html {.example}
|
||||
<div class="popup-strategy">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" strategy="fixed" active>
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
</div>
|
||||
|
||||
<wa-switch checked>Fixed</wa-switch>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.popup-strategy .overflow {
|
||||
position: relative;
|
||||
height: 300px;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.popup-strategy span[slot='anchor'] {
|
||||
display: inline-block;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
border: dashed 2px var(--wa-color-neutral-fill-loud);
|
||||
margin: 150px 50px;
|
||||
}
|
||||
|
||||
.popup-strategy .box {
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
background: var(--wa-color-brand-fill-loud);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
}
|
||||
|
||||
.popup-strategy wa-switch {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const container = document.querySelector('.popup-strategy');
|
||||
const popup = container.querySelector('wa-popup');
|
||||
const fixed = container.querySelector('wa-switch');
|
||||
|
||||
fixed.addEventListener('change', () => (popup.strategy = fixed.checked ? 'fixed' : 'absolute'));
|
||||
</script>
|
||||
```
|
||||
|
||||
### Flip
|
||||
|
||||
When the popup doesn't have enough room in its preferred placement, it can automatically flip to keep it in view. To enable this, use the `flip` attribute. By default, the popup will flip to the opposite placement, but you can configure preferred fallback placements using `flip-fallback-placement` and `flip-fallback-strategy`. Additional options are available to control the flip behavior's boundary and padding.
|
||||
When the popup doesn't have enough room in its preferred placement, it can automatically flip to keep it in view and visually connected to its anchor.
|
||||
To enable this, use the `flip` attribute. By default, the popup will flip to the opposite placement, but you can configure preferred fallback placements using `flip-fallback-placement` and `flip-fallback-strategy`. Additional options are available to control the flip behavior's boundary and padding.
|
||||
|
||||
Scroll the container to see how the popup flips to prevent clipping.
|
||||
|
||||
@@ -592,7 +534,7 @@ Scroll the container to see how the popup changes it's fallback placement to pre
|
||||
```html {.example}
|
||||
<div class="popup-flip-fallbacks">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" flip flip-fallback-placements="right bottom" flip-fallback-strategy="initial" active>
|
||||
<wa-popup placement="top" flip flip-fallback-placements="right bottom" flip-fallback-strategy="initial" active boundary="scroll">
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
@@ -626,14 +568,18 @@ Scroll the container to see how the popup changes it's fallback placement to pre
|
||||
|
||||
### Shift
|
||||
|
||||
When a popup is longer than its anchor, it risks being clipped by an overflowing container. In this case, use the `shift` attribute to shift the popup along its axis and back into view. You can customize the shift behavior using `shiftBoundary` and `shift-padding`.
|
||||
When a popup is longer than its anchor, it risks overflowing.
|
||||
In this case, use the `shift` attribute to shift the popup along its axis and back into view. You can customize the shift behavior using `shiftBoundary` and `shift-padding`.
|
||||
|
||||
By default, auto-size takes effect when the popup would overflow the viewport.
|
||||
You can use `boundary="scroll"` to make the popup resize when it overflows its nearest scrollable container instead.
|
||||
|
||||
Toggle the switch to see the difference.
|
||||
|
||||
```html {.example}
|
||||
<div class="popup-shift">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" shift shift-padding="10" active>
|
||||
<wa-popup placement="top" shift shift-padding="10" active boundary="scroll">
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
@@ -676,7 +622,11 @@ Toggle the switch to see the difference.
|
||||
|
||||
### Auto-size
|
||||
|
||||
Use the `auto-size` attribute to tell the popup to resize when necessary to prevent it from getting clipped. Possible values are `horizontal`, `vertical`, and `both`. You can use `autoSizeBoundary` and `auto-size-padding` to customize the behavior of this option. Auto-size works well with `flip`, but if you're using `auto-size-padding` make sure `flip-padding` is the same value.
|
||||
Use the `auto-size` attribute to tell the popup to resize when necessary to prevent it from overflowing.
|
||||
Possible values are `horizontal`, `vertical`, and `both`. You can use `autoSizeBoundary` and `auto-size-padding` to customize the behavior of this option. Auto-size works well with `flip`, but if you're using `auto-size-padding` make sure `flip-padding` is the same value.
|
||||
|
||||
By default, auto-size takes effect when the popup would overflow the viewport.
|
||||
You can use `boundary="scroll"` to make the popup resize when it overflows its nearest scrollable container instead.
|
||||
|
||||
When using `auto-size`, one or both of `--auto-size-available-width` and `--auto-size-available-height` will be applied to the host element. These values determine the available space the popover has before clipping will occur. Since they cascade, you can use them to set a max-width/height on your popup's content and easily control its overflow.
|
||||
|
||||
@@ -685,7 +635,7 @@ Scroll the container to see the popup resize as its available space changes.
|
||||
```html {.example}
|
||||
<div class="popup-auto-size">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" auto-size="both" auto-size-padding="10" active>
|
||||
<wa-popup placement="top" auto-size="both" auto-size-padding="10" active boundary="scroll">
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
|
||||
@@ -425,11 +425,3 @@ This can be hard to conceptualize, so heres a fairly large example showing how l
|
||||
</script>
|
||||
```
|
||||
|
||||
<script type="module">
|
||||
//
|
||||
// TODO - remove once we switch to the Popover API
|
||||
//
|
||||
customElements.whenDefined('wa-select').then(() => {
|
||||
document.querySelectorAll('wa-code-demo [slot="preview"] wa-select').forEach(select => select.hoist = true);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -152,25 +152,3 @@ Use the `--max-width` custom property to change the width the tooltip can grow t
|
||||
<wa-button id="wrapping-tooltip">Hover me</wa-button>
|
||||
```
|
||||
|
||||
### Hoisting
|
||||
|
||||
Tooltips will be clipped if they're inside a container that has `overflow: auto|hidden|scroll`. The `hoist` attribute forces the tooltip to use a fixed positioning strategy, allowing it to break out of the container. In this case, the tooltip will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html {.example}
|
||||
<div class="tooltip-hoist">
|
||||
<wa-tooltip for="no-hoist">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="no-hoist">No Hoist</wa-button>
|
||||
|
||||
<wa-tooltip for="hoist" hoist>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="hoist">Hoist</wa-button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.tooltip-hoist {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
padding: var(--wa-space-m);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -1632,18 +1632,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.6.12",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
|
||||
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
|
||||
"version": "1.6.13",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
|
||||
"integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.6.0",
|
||||
"@floating-ui/utils": "^0.2.8"
|
||||
"@floating-ui/utils": "^0.2.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
|
||||
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
|
||||
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@github/catalyst": {
|
||||
"version": "1.6.0",
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@floating-ui/dom": "^1.6.12",
|
||||
"@floating-ui/dom": "^1.6.13",
|
||||
"@shoelace-style/animations": "^1.2.0",
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.6",
|
||||
|
||||
@@ -210,12 +210,6 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
/** Disables the color picker. */
|
||||
@property({ type: Boolean }) disabled = false;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
/** Shows the opacity slider. Enabling this will cause the formatted value to be HEXA, RGBA, or HSLA. */
|
||||
@property({ type: Boolean }) opacity = false;
|
||||
|
||||
@@ -1097,7 +1091,6 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
aria-disabled=${this.disabled ? 'true' : 'false'}
|
||||
.containingElement=${this}
|
||||
?disabled=${this.disabled}
|
||||
?hoist=${this.hoist}
|
||||
@wa-after-show=${this.handleAfterShow}
|
||||
@wa-after-hide=${this.handleAfterHide}
|
||||
>
|
||||
|
||||
@@ -97,13 +97,6 @@ export default class WaCopyButton extends WebAwesomeElement {
|
||||
/** The preferred placement of the tooltip. */
|
||||
@property({ attribute: 'tooltip-placement' }) tooltipPlacement: 'top' | 'right' | 'bottom' | 'left' = 'top';
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the tooltip from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|hidden|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all,
|
||||
* scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
private async handleCopy() {
|
||||
if (this.disabled || this.isCopying) {
|
||||
return;
|
||||
@@ -220,7 +213,6 @@ export default class WaCopyButton extends WebAwesomeElement {
|
||||
for="copy-button"
|
||||
placement=${this.tooltipPlacement}
|
||||
?disabled=${this.disabled}
|
||||
?hoist=${this.hoist}
|
||||
exportparts="
|
||||
base:tooltip__base,
|
||||
base__popup:tooltip__base__popup,
|
||||
|
||||
@@ -95,12 +95,6 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
/** The distance in pixels from which to offset the panel along its trigger. */
|
||||
@property({ type: Number }) skidding = 0;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
/**
|
||||
* Syncs the popup width or height to that of the trigger element.
|
||||
*/
|
||||
@@ -415,7 +409,6 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
placement=${this.placement}
|
||||
distance=${this.distance}
|
||||
skidding=${this.skidding}
|
||||
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
||||
flip
|
||||
shift
|
||||
auto-size="vertical"
|
||||
|
||||
@@ -275,7 +275,6 @@ export class SubmenuController implements ReactiveController {
|
||||
flip
|
||||
flip-fallback-strategy="best-fit"
|
||||
skidding="${this.skidding}"
|
||||
strategy="fixed"
|
||||
auto-size="vertical"
|
||||
auto-size-padding="10"
|
||||
>
|
||||
|
||||
@@ -19,6 +19,19 @@
|
||||
isolation: isolate;
|
||||
max-width: var(--auto-size-available-width, none);
|
||||
max-height: var(--auto-size-available-height, none);
|
||||
|
||||
/* Clear UA styles for [popover] */
|
||||
:where(&) {
|
||||
inset: unset;
|
||||
padding: unset;
|
||||
margin: unset;
|
||||
width: unset;
|
||||
height: unset;
|
||||
color: unset;
|
||||
background: unset;
|
||||
border: unset;
|
||||
overflow: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.popup--fixed {
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import { arrow, autoUpdate, computePosition, flip, offset, platform, shift, size } from '@floating-ui/dom';
|
||||
import {
|
||||
arrow,
|
||||
autoUpdate,
|
||||
computePosition,
|
||||
flip,
|
||||
getOverflowAncestors,
|
||||
offset,
|
||||
platform,
|
||||
shift,
|
||||
size,
|
||||
} from '@floating-ui/dom';
|
||||
import { offsetParent } from 'composed-offset-position';
|
||||
import type { PropertyValues } from 'lit';
|
||||
import { html } from 'lit';
|
||||
@@ -23,6 +33,8 @@ function isVirtualElement(e: unknown): e is VirtualElement {
|
||||
);
|
||||
}
|
||||
|
||||
const SUPPORTS_POPOVER = globalThis?.HTMLElement?.prototype.hasOwnProperty('popover');
|
||||
|
||||
/**
|
||||
* @summary Popup is a utility that lets you declaratively anchor "popup" containers to another element.
|
||||
* @documentation https://backers.webawesome.com/docs/components/popup
|
||||
@@ -97,11 +109,8 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
| 'left-start'
|
||||
| 'left-end' = 'top';
|
||||
|
||||
/**
|
||||
* Determines how the popup is positioned. The `absolute` strategy works well in most cases, but if overflow is
|
||||
* clipped, using a `fixed` position strategy can often workaround it.
|
||||
*/
|
||||
@property({ reflect: true }) strategy: 'absolute' | 'fixed' = 'absolute';
|
||||
/** Which bounding box to use for flipping, shifting, and auto-sizing? */
|
||||
@property() boundary: 'viewport' | 'scroll' = 'viewport';
|
||||
|
||||
/** The distance in pixels from which to offset the panel away from its anchor. */
|
||||
@property({ type: Number }) distance = 0;
|
||||
@@ -281,6 +290,8 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
return;
|
||||
}
|
||||
|
||||
this.popup.showPopover?.();
|
||||
|
||||
this.cleanup = autoUpdate(this.anchorEl, this.popup, () => {
|
||||
this.reposition();
|
||||
});
|
||||
@@ -288,6 +299,8 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
|
||||
private async stop(): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.popup.hidePopover?.();
|
||||
|
||||
if (this.cleanup) {
|
||||
this.cleanup();
|
||||
this.cleanup = undefined;
|
||||
@@ -334,11 +347,25 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
this.popup.style.height = '';
|
||||
}
|
||||
|
||||
let overflowBoundary, defaultBoundary;
|
||||
|
||||
if (SUPPORTS_POPOVER && !isVirtualElement(this.anchor)) {
|
||||
// When using the Popover API, the floating element is no longer in the same DOM context
|
||||
// as the overflow ancestors so Floating-UI can't find them.
|
||||
// For flip, `elementContext: 'reference'` gets it to use the anchor element instead,
|
||||
// but the option is not available for shift() or size(), so we basically need to implement it ourselves.
|
||||
overflowBoundary = getOverflowAncestors(this.anchorEl as Element).filter(el => el instanceof Element);
|
||||
}
|
||||
|
||||
if (this.boundary === 'scroll') {
|
||||
defaultBoundary = overflowBoundary;
|
||||
}
|
||||
|
||||
// Then we flip
|
||||
if (this.flip) {
|
||||
middleware.push(
|
||||
flip({
|
||||
boundary: this.flipBoundary,
|
||||
boundary: this.flipBoundary || overflowBoundary,
|
||||
// @ts-expect-error - We're converting a string attribute to an array here
|
||||
fallbackPlacements: this.flipFallbackPlacements,
|
||||
fallbackStrategy: this.flipFallbackStrategy === 'best-fit' ? 'bestFit' : 'initialPlacement',
|
||||
@@ -351,7 +378,7 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
if (this.shift) {
|
||||
middleware.push(
|
||||
shift({
|
||||
boundary: this.shiftBoundary,
|
||||
boundary: this.shiftBoundary || defaultBoundary,
|
||||
padding: this.shiftPadding,
|
||||
}),
|
||||
);
|
||||
@@ -361,7 +388,7 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
if (this.autoSize) {
|
||||
middleware.push(
|
||||
size({
|
||||
boundary: this.autoSizeBoundary,
|
||||
boundary: this.autoSizeBoundary || defaultBoundary,
|
||||
padding: this.autoSizePadding,
|
||||
apply: ({ availableWidth, availableHeight }) => {
|
||||
if (this.autoSize === 'vertical' || this.autoSize === 'both') {
|
||||
@@ -399,15 +426,14 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
//
|
||||
// More info: https://github.com/shoelace-style/shoelace/issues/1135
|
||||
//
|
||||
const getOffsetParent =
|
||||
this.strategy === 'absolute'
|
||||
? (element: Element) => platform.getOffsetParent(element, offsetParent)
|
||||
: platform.getOffsetParent;
|
||||
const getOffsetParent = SUPPORTS_POPOVER
|
||||
? (element: Element) => platform.getOffsetParent(element, offsetParent)
|
||||
: platform.getOffsetParent;
|
||||
|
||||
computePosition(this.anchorEl, this.popup, {
|
||||
placement: this.placement,
|
||||
middleware,
|
||||
strategy: this.strategy,
|
||||
strategy: SUPPORTS_POPOVER ? 'absolute' : 'fixed',
|
||||
platform: {
|
||||
...platform,
|
||||
getOffsetParent,
|
||||
@@ -563,11 +589,12 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
></span>
|
||||
|
||||
<div
|
||||
popover="manual"
|
||||
part="popup"
|
||||
class=${classMap({
|
||||
popup: true,
|
||||
'popup--active': this.active,
|
||||
'popup--fixed': this.strategy === 'fixed',
|
||||
'popup--fixed': !SUPPORTS_POPOVER,
|
||||
'popup--has-arrow': this.arrow,
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -229,12 +229,6 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
*/
|
||||
@property({ type: Boolean, reflect: true }) open = false;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the listbox from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
/** The select's visual appearance. */
|
||||
@property({ reflect: true }) appearance: 'filled' | 'outlined' = 'outlined';
|
||||
|
||||
@@ -891,7 +885,6 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
'placeholder-visible': isPlaceholderVisible,
|
||||
})}
|
||||
placement=${this.placement}
|
||||
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
||||
flip
|
||||
shift
|
||||
sync="width"
|
||||
|
||||
@@ -92,13 +92,6 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
*/
|
||||
@property() trigger = 'hover focus';
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the tooltip from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|hidden|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all,
|
||||
* scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
@property() for: string | null = null;
|
||||
|
||||
@state() anchor: null | Element = null;
|
||||
@@ -290,7 +283,7 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
this.anchor = newAnchor;
|
||||
}
|
||||
|
||||
@watch(['distance', 'hoist', 'placement', 'skidding'])
|
||||
@watch(['distance', 'placement', 'skidding'])
|
||||
async handleOptionsChange() {
|
||||
if (this.hasUpdated) {
|
||||
await this.updateComplete;
|
||||
@@ -340,7 +333,6 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
placement=${this.placement}
|
||||
distance=${this.distance}
|
||||
skidding=${this.skidding}
|
||||
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
||||
flip
|
||||
shift
|
||||
arrow
|
||||
|
||||
Reference in New Issue
Block a user