floating: add constraint size option
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* for more details, examples, and original source.
|
||||
*/
|
||||
|
||||
import { computePosition, autoUpdate, flip, offset, type Placement } from '@floating-ui/dom';
|
||||
import { computePosition, autoUpdate, flip, offset, type Placement, size } from '@floating-ui/dom';
|
||||
import { createAttachmentKey } from 'svelte/attachments';
|
||||
|
||||
/**
|
||||
@@ -17,6 +17,13 @@ export interface PopoverOptions {
|
||||
placement?: Placement;
|
||||
/** Offset distance between the reference and floating elements (default: 8) */
|
||||
offset?: number;
|
||||
/**
|
||||
* Constraints the width and height of the popover to prevent it from
|
||||
* overflowing the viewport. If true, the popover will adjust its max-width
|
||||
* and max-height to fit. Scrolling is the responsibility of the parent
|
||||
* element. Default is true.
|
||||
*/
|
||||
constrainSize?: boolean;
|
||||
/** Callback when the popover is opened or closed */
|
||||
ontoggle?: (open: boolean) => void;
|
||||
}
|
||||
@@ -29,7 +36,8 @@ export class Popover {
|
||||
private options: PopoverOptions = {
|
||||
interaction: 'click',
|
||||
placement: 'bottom-start',
|
||||
offset: 8
|
||||
offset: 8,
|
||||
constrainSize: true
|
||||
};
|
||||
private referenceElement: HTMLElement | undefined = $state();
|
||||
private floatingElement: HTMLElement | undefined = $state();
|
||||
@@ -165,7 +173,21 @@ export class Popover {
|
||||
}
|
||||
const position = await computePosition(this.referenceElement, this.floatingElement, {
|
||||
placement: this.options.placement,
|
||||
middleware: [flip(), offset(this.options.offset)]
|
||||
middleware: [
|
||||
flip(),
|
||||
offset(this.options.offset),
|
||||
size({
|
||||
apply: ({ availableWidth, availableHeight, elements }) => {
|
||||
if (this.options.constrainSize) {
|
||||
elements.floating.style.maxWidth = `${availableWidth}px`;
|
||||
elements.floating.style.maxHeight = `${availableHeight}px`;
|
||||
} else {
|
||||
elements.floating.style.maxWidth = '';
|
||||
elements.floating.style.maxHeight = '';
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
});
|
||||
const { x, y } = position;
|
||||
Object.assign(this.floatingElement.style, {
|
||||
|
||||
Reference in New Issue
Block a user