sit-onyx 1.1.0-dev-20250930091245 → 1.1.0-dev-20250930101606

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.
@@ -51,6 +51,7 @@ declare const __VLS_component: import('vue').DefineComponent<OnyxBasicPopoverPro
51
51
  role: "menu" | "listbox" | "tree" | "grid" | "dialog";
52
52
  alignment: import('../../composables/useOpenAlignment.js', { with: { "resolution-mode": "import" } }).OpenAlignment | "auto";
53
53
  position: import('../../composables/useAnchorPositionPolyfill.js', { with: { "resolution-mode": "import" } }).AnchorPosition | "auto";
54
+ clipping: boolean;
54
55
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
55
56
  popoverWrapper: HTMLDivElement;
56
57
  popover: HTMLDivElement;
@@ -34,4 +34,6 @@ export type OnyxBasicPopoverProps = {
34
34
  * @default "dialog"
35
35
  */
36
36
  role?: "menu" | "listbox" | "tree" | "grid" | "dialog";
37
+ /** If true, the popover remains visible within the viewport even if its parent element scrolls out of view. */
38
+ clipping?: boolean;
37
39
  };
@@ -58,6 +58,7 @@ declare const __VLS_component: import('vue').DefineComponent<OnyxDialogProps, {}
58
58
  "onUpdate:open"?: ((open: boolean) => any) | undefined;
59
59
  }>, {
60
60
  open: boolean | null;
61
+ clipping: boolean;
61
62
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
62
63
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
63
64
  export default _default;
@@ -19,8 +19,8 @@ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
19
19
  declare const __VLS_component: import('vue').DefineComponent<OnyxListItemProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<OnyxListItemProps> & Readonly<{}>, {
20
20
  disabled: boolean;
21
21
  checked: boolean;
22
- selected: boolean;
23
22
  active: boolean;
23
+ selected: boolean;
24
24
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLLIElement>;
25
25
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
26
26
  export default _default;
@@ -1,14 +1,14 @@
1
1
  import { OnyxResizeHandleProps } from './types.js';
2
2
  declare const _default: import('vue').DefineComponent<OnyxResizeHandleProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
3
+ end: () => any;
4
+ start: () => any;
3
5
  updateWidth: (width: number) => any;
4
6
  autoSize: () => any;
5
- start: () => any;
6
- end: () => any;
7
7
  }, string, import('vue').PublicProps, Readonly<OnyxResizeHandleProps> & Readonly<{
8
+ onEnd?: (() => any) | undefined;
9
+ onStart?: (() => any) | undefined;
8
10
  onUpdateWidth?: ((width: number) => any) | undefined;
9
11
  onAutoSize?: (() => any) | undefined;
10
- onStart?: (() => any) | undefined;
11
- onEnd?: (() => any) | undefined;
12
12
  }>, {
13
13
  min: number;
14
14
  alignment: import('./types.js', { with: { "resolution-mode": "import" } }).ResizeHandleAlignment;
@@ -0,0 +1,16 @@
1
+ import { CSSProperties, Ref } from 'vue';
2
+ import { AnchorPosition } from './useAnchorPositionPolyfill.js';
3
+ import { OpenDirection } from './useOpenDirection.js';
4
+ export type UseClippingOptions = {
5
+ popoverRef: Ref<HTMLElement | null>;
6
+ popoverWrapperRef: Ref<HTMLElement | null>;
7
+ popoverPosition: Ref<AnchorPosition | OpenDirection>;
8
+ isVisible: Ref<boolean>;
9
+ clipping: Ref<boolean>;
10
+ };
11
+ export declare function useClipping(options: UseClippingOptions): {
12
+ clippingStyles: Ref<CSSProperties | undefined, CSSProperties | undefined>;
13
+ scrolledOut: Ref<OpenDirection | undefined, OpenDirection | undefined>;
14
+ isClipping: Ref<boolean, boolean>;
15
+ checkVisibilityOnScroll: () => void;
16
+ };
@@ -2294,6 +2294,82 @@ const useAnchorPositionPolyfill = ({
2294
2294
  useragentSupportsAnchorApi
2295
2295
  };
2296
2296
  };
2297
+ function useClipping(options) {
2298
+ const clippingStyles = ref();
2299
+ const scrolledOut = ref();
2300
+ const isClipping = ref(false);
2301
+ const checkVisibilityOnScroll = () => {
2302
+ const MIN_DISTANCE_TO_BORDER = 16;
2303
+ const MARGIN = 8;
2304
+ if (!options.popoverRef.value || !options.popoverWrapperRef.value || !options.isVisible.value)
2305
+ return;
2306
+ if (isClipping.value) {
2307
+ const popoverRect = options.popoverRef.value.getBoundingClientRect();
2308
+ const wrapperRect = options.popoverWrapperRef.value.getBoundingClientRect();
2309
+ const requiredHeight = popoverRect.height + MIN_DISTANCE_TO_BORDER + MARGIN;
2310
+ if (options.popoverPosition.value.includes("top")) {
2311
+ if (scrolledOut.value === "top" && wrapperRect.top > requiredHeight) {
2312
+ isClipping.value = false;
2313
+ return;
2314
+ }
2315
+ if (scrolledOut.value === "bottom" && wrapperRect.top + MARGIN < window.innerHeight) {
2316
+ isClipping.value = false;
2317
+ return;
2318
+ }
2319
+ } else if (options.popoverPosition.value.includes("bottom")) {
2320
+ if (scrolledOut.value === "top" && wrapperRect.bottom > MARGIN) {
2321
+ isClipping.value = false;
2322
+ return;
2323
+ }
2324
+ if (scrolledOut.value === "bottom" && window.innerHeight - wrapperRect.bottom > requiredHeight) {
2325
+ isClipping.value = false;
2326
+ return;
2327
+ }
2328
+ } else {
2329
+ if (scrolledOut.value === "top" && wrapperRect.top + MIN_DISTANCE_TO_BORDER > popoverRect.height) {
2330
+ isClipping.value = false;
2331
+ return;
2332
+ }
2333
+ if (scrolledOut.value === "bottom" && wrapperRect.bottom + MIN_DISTANCE_TO_BORDER < window.innerHeight) {
2334
+ isClipping.value = false;
2335
+ return;
2336
+ }
2337
+ }
2338
+ } else {
2339
+ const rect = options.popoverRef.value.getBoundingClientRect();
2340
+ const isTooHigh = rect.top < MIN_DISTANCE_TO_BORDER;
2341
+ const isTooLow = rect.bottom > window.innerHeight - MIN_DISTANCE_TO_BORDER;
2342
+ if (isTooHigh || isTooLow) {
2343
+ isClipping.value = true;
2344
+ if (isTooHigh) {
2345
+ scrolledOut.value = "top";
2346
+ clippingStyles.value = { left: rect.left + "px", top: "var(--onyx-density-md)" };
2347
+ } else if (isTooLow) {
2348
+ scrolledOut.value = "bottom";
2349
+ clippingStyles.value = { left: rect.left + "px", bottom: "var(--onyx-density-md)" };
2350
+ }
2351
+ }
2352
+ }
2353
+ };
2354
+ const disableClipping = computed(() => {
2355
+ return !options.clipping.value || !options.isVisible.value;
2356
+ });
2357
+ useGlobalEventListener({
2358
+ type: "scroll",
2359
+ listener: () => checkVisibilityOnScroll(),
2360
+ disabled: disableClipping
2361
+ });
2362
+ useGlobalEventListener({
2363
+ type: "resize",
2364
+ listener: () => checkVisibilityOnScroll(),
2365
+ disabled: disableClipping
2366
+ });
2367
+ onMounted(async () => {
2368
+ await nextTick();
2369
+ if (!disableClipping.value) checkVisibilityOnScroll();
2370
+ });
2371
+ return { clippingStyles, scrolledOut, isClipping, checkVisibilityOnScroll };
2372
+ }
2297
2373
  const useOpenAlignment = (element, tooltipElement, defaultPosition = "center") => {
2298
2374
  const minMargin = 16;
2299
2375
  const openAlignment = ref(defaultPosition);
@@ -2382,7 +2458,8 @@ const _sfc_main$1s = /* @__PURE__ */ defineComponent({
2382
2458
  alignment: { type: String, required: false, default: "auto" },
2383
2459
  fitParent: { type: Boolean, required: false },
2384
2460
  disabled: { type: Boolean, required: false },
2385
- role: { type: String, required: false, default: "dialog" }
2461
+ role: { type: String, required: false, default: "dialog" },
2462
+ clipping: { type: Boolean, required: false, default: false }
2386
2463
  },
2387
2464
  emits: ["update:open"],
2388
2465
  setup(__props, { expose: __expose, emit: __emit }) {
@@ -2413,13 +2490,16 @@ const _sfc_main$1s = /* @__PURE__ */ defineComponent({
2413
2490
  const positionAndAlignment = computed(() => {
2414
2491
  if (popoverPosition.value === "top" || popoverPosition.value === "bottom") {
2415
2492
  if (popoverAlignment.value === "left") {
2416
- return popoverPosition.value + " span-right";
2493
+ return `${popoverPosition.value} span-right`;
2417
2494
  }
2418
2495
  if (popoverAlignment.value === "right") {
2419
- return popoverPosition.value + " span-left";
2496
+ return `${popoverPosition.value} span-left`;
2420
2497
  }
2421
2498
  }
2422
- return popoverPosition.value;
2499
+ if (popoverPosition.value.includes(" ")) {
2500
+ return popoverPosition.value;
2501
+ }
2502
+ return `${popoverPosition.value} center`;
2423
2503
  });
2424
2504
  const popoverRef = useTemplateRef("popover");
2425
2505
  const popoverWrapperRef = useTemplateRef("popoverWrapper");
@@ -2450,6 +2530,13 @@ const _sfc_main$1s = /* @__PURE__ */ defineComponent({
2450
2530
  updateOpenDirection();
2451
2531
  updateOpenAlignment();
2452
2532
  };
2533
+ const { clippingStyles, isClipping } = useClipping({
2534
+ popoverRef,
2535
+ popoverWrapperRef,
2536
+ popoverPosition,
2537
+ isVisible,
2538
+ clipping: computed(() => props.clipping)
2539
+ });
2453
2540
  useGlobalEventListener({
2454
2541
  type: "resize",
2455
2542
  listener: () => updateDirections()
@@ -2484,6 +2571,7 @@ const _sfc_main$1s = /* @__PURE__ */ defineComponent({
2484
2571
  [`onyx-basic-popover__dialog--alignment-${popoverAlignment.value}`]: true,
2485
2572
  "onyx-basic-popover__dialog--fitparent": props.fitParent,
2486
2573
  "onyx-basic-popover__dialog--disabled": disabled.value,
2574
+ "onyx-basic-popover__dialog--clipping": isClipping.value,
2487
2575
  "onyx-basic-popover__dialog--dont-support-anchor": !useragentSupportsAnchorApi.value
2488
2576
  };
2489
2577
  });
@@ -2514,7 +2602,7 @@ const _sfc_main$1s = /* @__PURE__ */ defineComponent({
2514
2602
  top: topPosition.value
2515
2603
  };
2516
2604
  });
2517
- const __returned__ = { props, emit, _isVisible, isVisible, popoverPosition, popoverAlignment, disabled, positionAndAlignment, popoverRef, popoverWrapperRef, openDirection, updateOpenDirection, openAlignment, updateOpenAlignment, leftPosition, topPosition, updateAnchorPositionPolyfill, useragentSupportsAnchorApi, width, handleOpening, updateDirections, toggle, trigger, id, anchorName, popoverClasses, popoverStyles };
2605
+ const __returned__ = { props, emit, _isVisible, isVisible, popoverPosition, popoverAlignment, disabled, positionAndAlignment, popoverRef, popoverWrapperRef, openDirection, updateOpenDirection, openAlignment, updateOpenAlignment, leftPosition, topPosition, updateAnchorPositionPolyfill, useragentSupportsAnchorApi, width, handleOpening, updateDirections, clippingStyles, isClipping, toggle, trigger, id, anchorName, popoverClasses, popoverStyles };
2518
2606
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2519
2607
  return __returned__;
2520
2608
  }
@@ -2536,7 +2624,7 @@ function _sfc_render$1s(_ctx, _cache, $props, $setup, $data, $options) {
2536
2624
  "aria-label": $setup.props.label,
2537
2625
  popover: "manual",
2538
2626
  class: normalizeClass(["onyx-basic-popover__dialog", $setup.popoverClasses]),
2539
- style: normalizeStyle($setup.popoverStyles)
2627
+ style: normalizeStyle(!$setup.isClipping ? $setup.popoverStyles : $setup.clippingStyles)
2540
2628
  }, [
2541
2629
  renderSlot(_ctx.$slots, "content")
2542
2630
  ], 14, _hoisted_1$11)
@@ -8742,6 +8830,7 @@ const _sfc_main$H = /* @__PURE__ */ defineComponent({
8742
8830
  position: { type: String, required: false },
8743
8831
  alignment: { type: String, required: false },
8744
8832
  disabled: { type: Boolean, required: false },
8833
+ clipping: { type: Boolean, required: false, default: true },
8745
8834
  nonDismissible: { type: Boolean, required: false }
8746
8835
  },
8747
8836
  emits: ["update:open"],