floating: add constraint size option
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
* for more details, examples, and original source.
|
* 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';
|
import { createAttachmentKey } from 'svelte/attachments';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,6 +17,13 @@ export interface PopoverOptions {
|
|||||||
placement?: Placement;
|
placement?: Placement;
|
||||||
/** Offset distance between the reference and floating elements (default: 8) */
|
/** Offset distance between the reference and floating elements (default: 8) */
|
||||||
offset?: number;
|
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 */
|
/** Callback when the popover is opened or closed */
|
||||||
ontoggle?: (open: boolean) => void;
|
ontoggle?: (open: boolean) => void;
|
||||||
}
|
}
|
||||||
@@ -29,7 +36,8 @@ export class Popover {
|
|||||||
private options: PopoverOptions = {
|
private options: PopoverOptions = {
|
||||||
interaction: 'click',
|
interaction: 'click',
|
||||||
placement: 'bottom-start',
|
placement: 'bottom-start',
|
||||||
offset: 8
|
offset: 8,
|
||||||
|
constrainSize: true
|
||||||
};
|
};
|
||||||
private referenceElement: HTMLElement | undefined = $state();
|
private referenceElement: HTMLElement | undefined = $state();
|
||||||
private floatingElement: HTMLElement | undefined = $state();
|
private floatingElement: HTMLElement | undefined = $state();
|
||||||
@@ -165,7 +173,21 @@ export class Popover {
|
|||||||
}
|
}
|
||||||
const position = await computePosition(this.referenceElement, this.floatingElement, {
|
const position = await computePosition(this.referenceElement, this.floatingElement, {
|
||||||
placement: this.options.placement,
|
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;
|
const { x, y } = position;
|
||||||
Object.assign(this.floatingElement.style, {
|
Object.assign(this.floatingElement.style, {
|
||||||
|
|||||||
Reference in New Issue
Block a user