diff --git a/src/uix/soma/components/combobox/combobox-provider.svelte.ts b/src/uix/soma/components/combobox/combobox-provider.svelte.ts index 2d78099a3..d15ec5a57 100644 --- a/src/uix/soma/components/combobox/combobox-provider.svelte.ts +++ b/src/uix/soma/components/combobox/combobox-provider.svelte.ts @@ -532,7 +532,7 @@ interface ComboboxContentOpts align: Align; alignOffset: number; arrowPadding: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; sticky: 'partial' | 'always'; diff --git a/src/uix/soma/components/combobox/types.ts b/src/uix/soma/components/combobox/types.ts index 92b1b0244..469e7ea6b 100644 --- a/src/uix/soma/components/combobox/types.ts +++ b/src/uix/soma/components/combobox/types.ts @@ -91,8 +91,9 @@ export type ComboboxContentProps = WithChild< alignOffset?: number; /** Padding between arrow and content edges. @default 0 */ arrowPadding?: number; - /** Reposition to avoid viewport collisions. @default true */ - avoidCollisions?: boolean; + /** Collision avoidance vs the viewport — `true` = flip + shift, `'flip'` = + * flip-only (no slide; native CSS-anchor capable), `false` = none. @default true */ + avoidCollisions?: boolean | 'flip'; /** Collision boundary elements. @default [] */ collisionBoundary?: Arrayable; /** Padding from collision boundary in px. @default 0 */ diff --git a/src/uix/soma/components/context-menu/context-menu-provider.svelte.ts b/src/uix/soma/components/context-menu/context-menu-provider.svelte.ts index 705062c91..83d7f490c 100644 --- a/src/uix/soma/components/context-menu/context-menu-provider.svelte.ts +++ b/src/uix/soma/components/context-menu/context-menu-provider.svelte.ts @@ -211,7 +211,7 @@ interface ContextMenuContentOpts align: Align; alignOffset: number; arrowPadding: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; sticky: 'partial' | 'always'; @@ -958,7 +958,7 @@ interface ContextMenuSubContentOpts sideOffset: number; align: Align; alignOffset: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; loop: boolean; diff --git a/src/uix/soma/components/context-menu/types.ts b/src/uix/soma/components/context-menu/types.ts index e82e2bb6f..ca4c67303 100644 --- a/src/uix/soma/components/context-menu/types.ts +++ b/src/uix/soma/components/context-menu/types.ts @@ -51,7 +51,7 @@ export type ContextMenuContentProps = WithChild< /** @default 'start' */ align?: Align; /** @default 0 */ alignOffset?: number; /** @default 0 */ arrowPadding?: number; - /** @default true */ avoidCollisions?: boolean; + /** @default true */ avoidCollisions?: boolean | 'flip'; collisionBoundary?: Arrayable; /** @default 0 */ collisionPadding?: number | Partial>; /** @default 'partial' */ sticky?: 'partial' | 'always'; @@ -155,7 +155,7 @@ export type ContextMenuSubContentProps = WithChild< /** @default 0 */ sideOffset?: number; /** @default 'start' */ align?: Align; /** @default 0 */ alignOffset?: number; - /** @default true */ avoidCollisions?: boolean; + /** @default true */ avoidCollisions?: boolean | 'flip'; collisionBoundary?: Arrayable; /** @default 0 */ collisionPadding?: number | Partial>; /** @default false */ loop?: boolean; diff --git a/src/uix/soma/components/dropdown-menu/dropdown-menu-provider.svelte.ts b/src/uix/soma/components/dropdown-menu/dropdown-menu-provider.svelte.ts index 734e1858c..614e9ee1c 100644 --- a/src/uix/soma/components/dropdown-menu/dropdown-menu-provider.svelte.ts +++ b/src/uix/soma/components/dropdown-menu/dropdown-menu-provider.svelte.ts @@ -233,7 +233,7 @@ interface MenuContentOpts align: Align; alignOffset: number; arrowPadding: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; sticky: 'partial' | 'always'; @@ -1101,7 +1101,7 @@ interface MenuSubContentOpts sideOffset: number; align: Align; alignOffset: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; loop: boolean; diff --git a/src/uix/soma/components/dropdown-menu/types.ts b/src/uix/soma/components/dropdown-menu/types.ts index 8185adf1a..98590f9ff 100644 --- a/src/uix/soma/components/dropdown-menu/types.ts +++ b/src/uix/soma/components/dropdown-menu/types.ts @@ -43,7 +43,7 @@ export type MenuContentProps = WithChild< /** @default 'start' */ align?: Align; /** @default 0 */ alignOffset?: number; /** @default 0 */ arrowPadding?: number; - /** @default true */ avoidCollisions?: boolean; + /** @default true */ avoidCollisions?: boolean | 'flip'; collisionBoundary?: Arrayable; /** @default 0 */ collisionPadding?: number | Partial>; /** @default 'partial' */ sticky?: 'partial' | 'always'; @@ -173,7 +173,7 @@ export type MenuSubContentProps = WithChild< /** @default 0 */ sideOffset?: number; /** @default 'start' */ align?: Align; /** @default 0 */ alignOffset?: number; - /** @default true */ avoidCollisions?: boolean; + /** @default true */ avoidCollisions?: boolean | 'flip'; collisionBoundary?: Arrayable; /** @default 0 */ collisionPadding?: number | Partial>; /** @default false */ loop?: boolean; diff --git a/src/uix/soma/components/link-preview/link-preview-provider.svelte.ts b/src/uix/soma/components/link-preview/link-preview-provider.svelte.ts index 58f30612c..4bd21a6a2 100644 --- a/src/uix/soma/components/link-preview/link-preview-provider.svelte.ts +++ b/src/uix/soma/components/link-preview/link-preview-provider.svelte.ts @@ -239,7 +239,7 @@ interface LinkPreviewContentOpts align: Align; alignOffset: number; arrowPadding: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; sticky: 'partial' | 'always'; diff --git a/src/uix/soma/components/link-preview/types.ts b/src/uix/soma/components/link-preview/types.ts index 5bd0d5df8..66d95d617 100644 --- a/src/uix/soma/components/link-preview/types.ts +++ b/src/uix/soma/components/link-preview/types.ts @@ -57,7 +57,7 @@ export type LinkPreviewContentProps = WithChild< /** @default 'center' */ align?: Align; /** @default 0 */ alignOffset?: number; /** @default 0 */ arrowPadding?: number; - /** @default true */ avoidCollisions?: boolean; + /** @default true */ avoidCollisions?: boolean | 'flip'; collisionBoundary?: Arrayable; /** @default 0 */ collisionPadding?: number | Partial>; /** @default 'partial' */ sticky?: 'partial' | 'always'; diff --git a/src/uix/soma/components/select/select-provider.svelte.ts b/src/uix/soma/components/select/select-provider.svelte.ts index ed5b09ae8..a72a6466e 100644 --- a/src/uix/soma/components/select/select-provider.svelte.ts +++ b/src/uix/soma/components/select/select-provider.svelte.ts @@ -445,7 +445,7 @@ interface SelectContentOpts align: Align; alignOffset: number; arrowPadding: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; sticky: 'partial' | 'always'; diff --git a/src/uix/soma/components/select/types.ts b/src/uix/soma/components/select/types.ts index 66a8c5635..ba7f9f5e8 100644 --- a/src/uix/soma/components/select/types.ts +++ b/src/uix/soma/components/select/types.ts @@ -83,8 +83,9 @@ export type SelectContentProps = WithChild< alignOffset?: number; /** Padding between arrow and content edges. @default 0 */ arrowPadding?: number; - /** Reposition to avoid viewport collisions. @default true */ - avoidCollisions?: boolean; + /** Collision avoidance vs the viewport — `true` = flip + shift, `'flip'` = + * flip-only (no slide; native CSS-anchor capable), `false` = none. @default true */ + avoidCollisions?: boolean | 'flip'; /** Collision boundary elements. @default [] */ collisionBoundary?: Arrayable; /** Padding from collision boundary in px. @default 0 */ diff --git a/src/uix/soma/components/tooltip/tooltip-provider.svelte.ts b/src/uix/soma/components/tooltip/tooltip-provider.svelte.ts index 19c9b9a18..36e1a8abc 100644 --- a/src/uix/soma/components/tooltip/tooltip-provider.svelte.ts +++ b/src/uix/soma/components/tooltip/tooltip-provider.svelte.ts @@ -384,7 +384,7 @@ interface TooltipContentOpts align: Align; alignOffset: number; arrowPadding: number; - avoidCollisions: boolean; + avoidCollisions: boolean | 'flip'; collisionBoundary: Arrayable; collisionPadding: number | Partial>; sticky: 'partial' | 'always'; diff --git a/src/uix/soma/components/tooltip/types.ts b/src/uix/soma/components/tooltip/types.ts index 6b5be22ed..4bf2f76a0 100644 --- a/src/uix/soma/components/tooltip/types.ts +++ b/src/uix/soma/components/tooltip/types.ts @@ -73,8 +73,9 @@ export type TooltipContentProps = WithChild< alignOffset?: number; /** Padding between arrow and content edges. @default 0 */ arrowPadding?: number; - /** Reposition to avoid viewport collisions. @default true */ - avoidCollisions?: boolean; + /** Collision avoidance vs the viewport — `true` = flip + shift, `'flip'` = + * flip-only (no slide; native CSS-anchor capable), `false` = none. @default true */ + avoidCollisions?: boolean | 'flip'; /** Collision boundary elements. @default [] */ collisionBoundary?: Arrayable; /** Padding from collision boundary in px. @default 8 */ diff --git a/web/routes/uix/components/context-menu/+page.svelte b/web/routes/uix/components/context-menu/+page.svelte index 2c4c0fa53..b02911b3e 100644 --- a/web/routes/uix/components/context-menu/+page.svelte +++ b/web/routes/uix/components/context-menu/+page.svelte @@ -18,7 +18,7 @@ let sideOffset = $state(undefined); let align = $state<'start' | 'center' | 'end'>('start'); let alignOffset = $state(0); - let avoidCollisions = $state(true); + let avoidCollisions: boolean | 'flip' = $state(true); let loop = $state(false); let trapFocus = $state(false); let preventScroll = $state(false); @@ -102,7 +102,8 @@ sideOffset !== undefined && ` sideOffset={${sideOffset}}`, align !== 'start' && ` align="${align}"`, alignOffset !== 0 && ` alignOffset={${alignOffset}}`, - !avoidCollisions && ' avoidCollisions={false}', + avoidCollisions !== true && + ` avoidCollisions={${avoidCollisions === 'flip' ? "'flip'" : 'false'}}`, loop && ' loop', !trapFocus && ' trapFocus={false}', preventScroll && ' preventScroll', @@ -155,7 +156,8 @@ ' ', showGroupHeading && ' ', @@ -394,10 +396,11 @@ diff --git a/web/routes/uix/components/tooltip/+page.svelte b/web/routes/uix/components/tooltip/+page.svelte index bf1414648..36a652d91 100644 --- a/web/routes/uix/components/tooltip/+page.svelte +++ b/web/routes/uix/components/tooltip/+page.svelte @@ -35,7 +35,7 @@ let sideOffset = $state(8); let align = $state('center'); let alignOffset = $state(0); - let avoidCollisions = $state(true); + let avoidCollisions: boolean | 'flip' = $state(true); let sticky = $state<'partial' | 'always'>('partial'); let hideWhenDetached = $state(true); let forceMount = $state(false); @@ -107,7 +107,8 @@ sideOffset !== 0 && ` sideOffset={${sideOffset}}`, align !== 'center' && ` align="${align}"`, alignOffset !== 0 && ` alignOffset={${alignOffset}}`, - !avoidCollisions && ' avoidCollisions={false}', + avoidCollisions !== true && + ` avoidCollisions={${avoidCollisions === 'flip' ? "'flip'" : 'false'}}`, sticky !== 'partial' && ` sticky="${sticky}"`, !hideWhenDetached && ' hideWhenDetached={false}', forceMount && ' forceMount', @@ -382,12 +383,12 @@