@pathscale/ui 1.1.62 → 1.1.64

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.
@@ -0,0 +1 @@
1
+ export { createOverlayPosition, type OverlayPlacement, type OverlayAlign, type CreateOverlayPositionOptions, } from "./overlayPosition";
@@ -0,0 +1,3 @@
1
+ import * as __WEBPACK_EXTERNAL_MODULE__overlayPosition_js_25962dee__ from "./overlayPosition.js";
2
+ var __webpack_exports__createOverlayPosition = __WEBPACK_EXTERNAL_MODULE__overlayPosition_js_25962dee__.createOverlayPosition;
3
+ export { __webpack_exports__createOverlayPosition as createOverlayPosition };
@@ -0,0 +1,19 @@
1
+ import { type Accessor, type JSX } from "solid-js";
2
+ export type OverlayPlacement = "top" | "bottom" | "left" | "right";
3
+ export type OverlayAlign = "start" | "center" | "end";
4
+ export interface CreateOverlayPositionOptions {
5
+ open: Accessor<boolean>;
6
+ triggerRef: Accessor<HTMLElement | undefined>;
7
+ overlayRef: Accessor<HTMLElement | undefined>;
8
+ placement: Accessor<OverlayPlacement>;
9
+ offset: Accessor<number>;
10
+ autoFlip?: Accessor<boolean>;
11
+ align?: Accessor<OverlayAlign>;
12
+ matchTriggerWidth?: Accessor<boolean>;
13
+ minWidth?: Accessor<number | undefined>;
14
+ viewportPadding?: Accessor<number>;
15
+ }
16
+ export declare const createOverlayPosition: (options: CreateOverlayPositionOptions) => {
17
+ style: Accessor<JSX.CSSProperties>;
18
+ placement: Accessor<OverlayPlacement>;
19
+ };
@@ -0,0 +1,115 @@
1
+ import * as __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__ from "solid-js";
2
+ const oppositePlacement = {
3
+ top: "bottom",
4
+ bottom: "top",
5
+ left: "right",
6
+ right: "left"
7
+ };
8
+ const clamp = (value, min, max)=>{
9
+ if (max < min) return min;
10
+ return Math.min(Math.max(value, min), max);
11
+ };
12
+ const getMainAxisSize = (placement, rect)=>"top" === placement || "bottom" === placement ? rect.height : rect.width;
13
+ const getAvailableSpace = (rect, viewportWidth, viewportHeight, padding)=>({
14
+ top: rect.top - padding,
15
+ bottom: viewportHeight - rect.bottom - padding,
16
+ left: rect.left - padding,
17
+ right: viewportWidth - rect.right - padding
18
+ });
19
+ const resolvePlacement = (preferred, triggerRect, overlayRect, viewportWidth, viewportHeight, padding, offset, autoFlip)=>{
20
+ if (!autoFlip) return preferred;
21
+ const available = getAvailableSpace(triggerRect, viewportWidth, viewportHeight, padding);
22
+ const needed = getMainAxisSize(preferred, overlayRect) + offset;
23
+ if (available[preferred] >= needed) return preferred;
24
+ const opposite = oppositePlacement[preferred];
25
+ return available[opposite] > available[preferred] ? opposite : preferred;
26
+ };
27
+ const getCrossAxisCoordinate = (align, triggerStart, triggerSize, overlaySize)=>{
28
+ if ("start" === align) return triggerStart;
29
+ if ("end" === align) return triggerStart + triggerSize - overlaySize;
30
+ return triggerStart + (triggerSize - overlaySize) / 2;
31
+ };
32
+ const round = (value)=>Math.round(100 * value) / 100;
33
+ const createOverlayPosition = (options)=>{
34
+ const [style, setStyle] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)({
35
+ visibility: "hidden"
36
+ });
37
+ const [resolvedPlacement, setResolvedPlacement] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(options.placement());
38
+ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createEffect)(()=>{
39
+ if (!options.open()) {
40
+ setResolvedPlacement(options.placement());
41
+ setStyle({
42
+ visibility: "hidden"
43
+ });
44
+ return;
45
+ }
46
+ const trigger = options.triggerRef();
47
+ const overlay = options.overlayRef();
48
+ if (!trigger || !overlay) return;
49
+ const viewportPadding = options.viewportPadding?.() ?? 8;
50
+ const align = options.align?.() ?? "center";
51
+ const autoFlip = options.autoFlip?.() ?? true;
52
+ let frame = 0;
53
+ const update = ()=>{
54
+ const triggerRect = trigger.getBoundingClientRect();
55
+ const overlayRect = overlay.getBoundingClientRect();
56
+ const viewportWidth = window.innerWidth;
57
+ const viewportHeight = window.innerHeight;
58
+ const offset = options.offset();
59
+ const placement = resolvePlacement(options.placement(), triggerRect, overlayRect, viewportWidth, viewportHeight, viewportPadding, offset, autoFlip);
60
+ let top = 0;
61
+ let left = 0;
62
+ switch(placement){
63
+ case "top":
64
+ top = triggerRect.top - overlayRect.height - offset;
65
+ left = getCrossAxisCoordinate(align, triggerRect.left, triggerRect.width, overlayRect.width);
66
+ break;
67
+ case "bottom":
68
+ top = triggerRect.bottom + offset;
69
+ left = getCrossAxisCoordinate(align, triggerRect.left, triggerRect.width, overlayRect.width);
70
+ break;
71
+ case "left":
72
+ top = getCrossAxisCoordinate(align, triggerRect.top, triggerRect.height, overlayRect.height);
73
+ left = triggerRect.left - overlayRect.width - offset;
74
+ break;
75
+ case "right":
76
+ top = getCrossAxisCoordinate(align, triggerRect.top, triggerRect.height, overlayRect.height);
77
+ left = triggerRect.right + offset;
78
+ break;
79
+ }
80
+ const maxTop = viewportHeight - overlayRect.height - viewportPadding;
81
+ const maxLeft = viewportWidth - overlayRect.width - viewportPadding;
82
+ setResolvedPlacement(placement);
83
+ setStyle({
84
+ position: "fixed",
85
+ top: `${round(clamp(top, viewportPadding, maxTop))}px`,
86
+ left: `${round(clamp(left, viewportPadding, maxLeft))}px`,
87
+ "max-width": `${round(Math.max(0, viewportWidth - 2 * viewportPadding))}px`,
88
+ ...options.matchTriggerWidth?.() ? {
89
+ "min-width": `${round(Math.max(triggerRect.width, options.minWidth?.() ?? 0))}px`
90
+ } : {}
91
+ });
92
+ };
93
+ const schedule = ()=>{
94
+ cancelAnimationFrame(frame);
95
+ frame = requestAnimationFrame(update);
96
+ };
97
+ schedule();
98
+ window.addEventListener("resize", schedule);
99
+ window.addEventListener("scroll", schedule, true);
100
+ const resizeObserver = "undefined" != typeof ResizeObserver ? new ResizeObserver(schedule) : void 0;
101
+ resizeObserver?.observe(trigger);
102
+ resizeObserver?.observe(overlay);
103
+ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.onCleanup)(()=>{
104
+ cancelAnimationFrame(frame);
105
+ window.removeEventListener("resize", schedule);
106
+ window.removeEventListener("scroll", schedule, true);
107
+ resizeObserver?.disconnect();
108
+ });
109
+ });
110
+ return {
111
+ style,
112
+ placement: resolvedPlacement
113
+ };
114
+ };
115
+ export { createOverlayPosition };
@@ -71,10 +71,8 @@
71
71
  }
72
72
 
73
73
  .dropdown__popover {
74
- position: absolute;
74
+ position: fixed;
75
75
  z-index: 80;
76
- top: calc(100% + var(--dropdown-offset, 6px));
77
- inset-inline-start: 0;
78
76
  min-width: min(13.75rem, calc(100vw - 2rem));
79
77
  max-width: min(48svw, calc(100vw - 2rem));
80
78
  max-height: min(24rem, 70vh);
@@ -101,13 +99,44 @@
101
99
  .dropdown__popover[data-open="true"] {
102
100
  visibility: visible;
103
101
  opacity: 1;
104
- transform: translateY(0) scale(1);
102
+ transform: scale(1);
105
103
  pointer-events: auto;
106
104
  }
107
105
 
108
- .dropdown__popover[data-align="end"] {
109
- inset-inline-start: auto;
110
- inset-inline-end: 0;
106
+ .dropdown__popover[data-placement="top"] {
107
+ transform: translateY(4px) scale(0.96);
108
+ transform-origin: bottom;
109
+ }
110
+
111
+ .dropdown__popover[data-placement="top"][data-open="true"] {
112
+ transform: translateY(0) scale(1);
113
+ }
114
+
115
+ .dropdown__popover[data-placement="bottom"] {
116
+ transform: translateY(-4px) scale(0.96);
117
+ transform-origin: top;
118
+ }
119
+
120
+ .dropdown__popover[data-placement="bottom"][data-open="true"] {
121
+ transform: translateY(0) scale(1);
122
+ }
123
+
124
+ .dropdown__popover[data-placement="left"] {
125
+ transform: translateX(4px) scale(0.96);
126
+ transform-origin: right;
127
+ }
128
+
129
+ .dropdown__popover[data-placement="left"][data-open="true"] {
130
+ transform: translateX(0) scale(1);
131
+ }
132
+
133
+ .dropdown__popover[data-placement="right"] {
134
+ transform: translateX(-4px) scale(0.96);
135
+ transform-origin: left;
136
+ }
137
+
138
+ .dropdown__popover[data-placement="right"][data-open="true"] {
139
+ transform: translateX(0) scale(1);
111
140
  }
112
141
 
113
142
  .dropdown__menu {
@@ -1,11 +1,15 @@
1
1
  import "./Dropdown.css";
2
2
  import { type JSX } from "solid-js";
3
+ import { type OverlayPlacement } from "../_shared/overlayPosition";
3
4
  type DropdownAlign = "start" | "end";
5
+ type DropdownPlacement = OverlayPlacement;
4
6
  type DropdownRootProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, "onChange"> & {
5
7
  children: JSX.Element;
6
8
  open?: boolean;
7
9
  defaultOpen?: boolean;
8
10
  onOpenChange?: (open: boolean) => void;
11
+ placement?: DropdownPlacement;
12
+ autoFlip?: boolean;
9
13
  disabled?: boolean;
10
14
  dataTheme?: string;
11
15
  className?: string;
@@ -15,6 +19,8 @@ type DropdownTriggerProps = JSX.ButtonHTMLAttributes<HTMLButtonElement>;
15
19
  declare const DropdownTrigger: (props: DropdownTriggerProps) => JSX.Element;
16
20
  type DropdownMenuProps = JSX.HTMLAttributes<HTMLDivElement> & {
17
21
  align?: DropdownAlign;
22
+ placement?: DropdownPlacement;
23
+ autoFlip?: boolean;
18
24
  sideOffset?: number;
19
25
  };
20
26
  declare const DropdownMenu: (props: DropdownMenuProps) => JSX.Element;
@@ -35,4 +41,4 @@ declare const Dropdown: ((props: DropdownRootProps) => JSX.Element) & {
35
41
  Separator: (props: DropdownSeparatorProps) => JSX.Element;
36
42
  };
37
43
  export { Dropdown as default, Dropdown, DropdownRoot, DropdownTrigger, DropdownMenu, DropdownItem, DropdownGroup, DropdownSeparator, };
38
- export type { DropdownAlign, DropdownRootProps, DropdownTriggerProps, DropdownMenuProps, DropdownItemProps, DropdownGroupProps, DropdownSeparatorProps, };
44
+ export type { DropdownAlign, DropdownPlacement, DropdownRootProps, DropdownTriggerProps, DropdownMenuProps, DropdownItemProps, DropdownGroupProps, DropdownSeparatorProps, };
@@ -2,6 +2,7 @@ import * as __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__ from "solid-js/web
2
2
  import "./Dropdown.css";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__ from "solid-js";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE_tailwind_merge_e05e3e95__ from "tailwind-merge";
5
+ import * as __WEBPACK_EXTERNAL_MODULE__shared_overlayPosition_js_ab299723__ from "../_shared/overlayPosition.js";
5
6
  import * as __WEBPACK_EXTERNAL_MODULE__Dropdown_classes_js_de10768c__ from "./Dropdown.classes.js";
6
7
  var _tmpl$ = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)("<div>"), _tmpl$2 = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)("<button>"), _tmpl$3 = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)("<div><div>");
7
8
  const DropdownContext = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createContext)();
@@ -25,6 +26,8 @@ const DropdownRoot = (props)=>{
25
26
  "open",
26
27
  "defaultOpen",
27
28
  "onOpenChange",
29
+ "placement",
30
+ "autoFlip",
28
31
  "disabled",
29
32
  "dataTheme",
30
33
  "className",
@@ -38,10 +41,13 @@ const DropdownRoot = (props)=>{
38
41
  const [focusedKey, setFocusedKey] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(void 0);
39
42
  const [focusRequest, setFocusRequest] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(null);
40
43
  const [triggerRef, setTriggerRefSignal] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(void 0);
44
+ const [menuRef, setMenuRefSignal] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(void 0);
41
45
  const [rootRef, setRootRefSignal] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(void 0);
42
46
  const isControlled = ()=>void 0 !== local.open;
43
47
  const isDisabled = ()=>Boolean(local.disabled);
44
48
  const open = ()=>isControlled() ? Boolean(local.open) : internalOpen();
49
+ const placement = ()=>local.placement ?? "bottom";
50
+ const autoFlip = ()=>local.autoFlip ?? true;
45
51
  const setRootRef = (el)=>{
46
52
  setRootRefSignal(el);
47
53
  if ("function" == typeof local.ref) local.ref(el);
@@ -49,6 +55,9 @@ const DropdownRoot = (props)=>{
49
55
  const setTriggerRef = (el)=>{
50
56
  setTriggerRefSignal(el);
51
57
  };
58
+ const setMenuRef = (el)=>{
59
+ setMenuRefSignal(el);
60
+ };
52
61
  const getEnabledItems = ()=>items().filter((item)=>!item.disabled);
53
62
  const focusItem = (item)=>{
54
63
  if (!item) return;
@@ -114,9 +123,10 @@ const DropdownRoot = (props)=>{
114
123
  (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.onMount)(()=>{
115
124
  const handlePointerDown = (event)=>{
116
125
  if (!open()) return;
117
- const root = rootRef();
118
- if (!root) return;
119
- if (root.contains(event.target)) return;
126
+ const target = event.target;
127
+ if (rootRef()?.contains(target)) return;
128
+ if (menuRef()?.contains(target)) return;
129
+ if (triggerRef()?.contains(target)) return;
120
130
  setOpen(false);
121
131
  };
122
132
  document.addEventListener("pointerdown", handlePointerDown);
@@ -130,6 +140,10 @@ const DropdownRoot = (props)=>{
130
140
  disabled: isDisabled,
131
141
  triggerId,
132
142
  menuId,
143
+ placement,
144
+ autoFlip,
145
+ triggerRef,
146
+ menuRef,
133
147
  focusedKey,
134
148
  setFocusedKey,
135
149
  setOpen,
@@ -140,6 +154,7 @@ const DropdownRoot = (props)=>{
140
154
  registerItem,
141
155
  unregisterItem,
142
156
  setTriggerRef,
157
+ setMenuRef,
143
158
  setRootRef
144
159
  },
145
160
  get children () {
@@ -267,6 +282,8 @@ const DropdownMenu = (props)=>{
267
282
  "class",
268
283
  "children",
269
284
  "align",
285
+ "placement",
286
+ "autoFlip",
270
287
  "sideOffset",
271
288
  "onKeyDown",
272
289
  "style",
@@ -283,6 +300,15 @@ const DropdownMenu = (props)=>{
283
300
  (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.insert)(_el$5, ()=>local.children);
284
301
  return _el$4;
285
302
  })();
303
+ const overlayPosition = (0, __WEBPACK_EXTERNAL_MODULE__shared_overlayPosition_js_ab299723__.createOverlayPosition)({
304
+ open: ctx.open,
305
+ triggerRef: ctx.triggerRef,
306
+ overlayRef: ctx.menuRef,
307
+ placement: ()=>local.placement ?? ctx.placement(),
308
+ offset: ()=>local.sideOffset ?? 6,
309
+ autoFlip: ()=>local.autoFlip ?? ctx.autoFlip(),
310
+ align: ()=>"end" === local.align ? "end" : "start"
311
+ });
286
312
  const handleKeyDown = (event)=>{
287
313
  invokeEventHandler(local.onKeyDown, event);
288
314
  if (event.defaultPrevented) return;
@@ -317,47 +343,65 @@ const DropdownMenu = (props)=>{
317
343
  }
318
344
  };
319
345
  const menuStyle = ()=>{
320
- if ("string" == typeof local.style) return `${local.style}; --dropdown-offset: ${local.sideOffset ?? 6}px;`;
346
+ const overlayStyle = overlayPosition.style();
347
+ if ("string" == typeof local.style) return [
348
+ local.style,
349
+ Object.entries(overlayStyle).map(([key, value])=>`${key}: ${String(value)}`).join("; ")
350
+ ].filter(Boolean).join("; ");
321
351
  return {
322
352
  ...local.style ?? {},
323
- "--dropdown-offset": `${local.sideOffset ?? 6}px`
353
+ ...overlayStyle
324
354
  };
325
355
  };
326
- return (()=>{
327
- var _el$6 = _tmpl$3(), _el$7 = _el$6.firstChild;
328
- (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.spread)(_el$6, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.mergeProps)(others, {
329
- get id () {
330
- return ctx.menuId;
331
- }
332
- }, ()=>({
333
- class: (0, __WEBPACK_EXTERNAL_MODULE_tailwind_merge_e05e3e95__.twMerge)(__WEBPACK_EXTERNAL_MODULE__Dropdown_classes_js_de10768c__.CLASSES.slot.popover, local.class)
334
- }), {
335
- get role () {
336
- return local.role ?? "menu";
337
- },
338
- "data-slot": "dropdown-popover",
339
- get ["data-open"] () {
340
- return ctx.open() ? "true" : "false";
341
- },
342
- get ["data-align"] () {
343
- return local.align ?? "start";
344
- },
345
- get ["aria-hidden"] () {
346
- return ctx.open() ? "false" : "true";
347
- },
348
- get style () {
349
- return menuStyle();
350
- },
351
- onKeyDown: handleKeyDown
352
- }), false, true);
353
- (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.spread)(_el$7, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.mergeProps)(()=>({
354
- class: __WEBPACK_EXTERNAL_MODULE__Dropdown_classes_js_de10768c__.CLASSES.slot.menu
355
- }), {
356
- "data-slot": "dropdown-menu"
357
- }), false, true);
358
- (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.insert)(_el$7, ()=>local.children);
359
- return _el$6;
360
- })();
356
+ return (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.createComponent)(__WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.Show, {
357
+ get when () {
358
+ return ctx.open();
359
+ },
360
+ get children () {
361
+ return (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.createComponent)(__WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.Portal, {
362
+ get children () {
363
+ var _el$6 = _tmpl$3(), _el$7 = _el$6.firstChild;
364
+ var _ref$ = ctx.setMenuRef;
365
+ "function" == typeof _ref$ ? (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.use)(_ref$, _el$6) : ctx.setMenuRef = _el$6;
366
+ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.spread)(_el$6, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.mergeProps)(others, {
367
+ get id () {
368
+ return ctx.menuId;
369
+ }
370
+ }, ()=>({
371
+ class: (0, __WEBPACK_EXTERNAL_MODULE_tailwind_merge_e05e3e95__.twMerge)(__WEBPACK_EXTERNAL_MODULE__Dropdown_classes_js_de10768c__.CLASSES.slot.popover, local.class)
372
+ }), {
373
+ get role () {
374
+ return local.role ?? "menu";
375
+ },
376
+ "data-slot": "dropdown-popover",
377
+ get ["data-open"] () {
378
+ return ctx.open() ? "true" : "false";
379
+ },
380
+ get ["data-align"] () {
381
+ return local.align ?? "start";
382
+ },
383
+ get ["data-placement"] () {
384
+ return overlayPosition.placement();
385
+ },
386
+ get ["aria-hidden"] () {
387
+ return ctx.open() ? "false" : "true";
388
+ },
389
+ get style () {
390
+ return menuStyle();
391
+ },
392
+ onKeyDown: handleKeyDown
393
+ }), false, true);
394
+ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.spread)(_el$7, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.mergeProps)(()=>({
395
+ class: __WEBPACK_EXTERNAL_MODULE__Dropdown_classes_js_de10768c__.CLASSES.slot.menu
396
+ }), {
397
+ "data-slot": "dropdown-menu"
398
+ }), false, true);
399
+ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.insert)(_el$7, ()=>local.children);
400
+ return _el$6;
401
+ }
402
+ });
403
+ }
404
+ });
361
405
  };
362
406
  const DropdownItem = (props)=>{
363
407
  const ctx = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.useContext)(DropdownContext);
@@ -1,2 +1,2 @@
1
1
  export { default, Dropdown } from "./Dropdown";
2
- export type { DropdownAlign, DropdownRootProps, DropdownTriggerProps, DropdownMenuProps, DropdownItemProps, DropdownGroupProps, DropdownSeparatorProps, } from "./Dropdown";
2
+ export type { DropdownAlign, DropdownPlacement, DropdownRootProps, DropdownTriggerProps, DropdownMenuProps, DropdownItemProps, DropdownGroupProps, DropdownSeparatorProps, } from "./Dropdown";
@@ -5,7 +5,7 @@
5
5
  }
6
6
 
7
7
  .popover {
8
- position: absolute;
8
+ position: fixed;
9
9
  z-index: var(--z-overlay, 70);
10
10
  border-radius: 1.5rem;
11
11
  padding: 0;
@@ -26,51 +26,43 @@
26
26
  .popover[data-open="true"] {
27
27
  opacity: 1;
28
28
  pointer-events: auto;
29
- transform: translateY(0) scale(1);
29
+ transform: scale(1);
30
30
  }
31
31
 
32
32
  .popover[data-placement="top"] {
33
- bottom: calc(100% + var(--popover-offset, 8px));
34
- left: 50%;
35
- transform: translateX(-50%) translateY(4px) scale(0.96);
33
+ transform: translateY(4px) scale(0.96);
36
34
  transform-origin: bottom;
37
35
  }
38
36
 
39
37
  .popover[data-placement="top"][data-open="true"] {
40
- transform: translateX(-50%) translateY(0) scale(1);
38
+ transform: translateY(0) scale(1);
41
39
  }
42
40
 
43
41
  .popover[data-placement="bottom"] {
44
- top: calc(100% + var(--popover-offset, 8px));
45
- left: 50%;
46
- transform: translateX(-50%) translateY(-4px) scale(0.96);
42
+ transform: translateY(-4px) scale(0.96);
47
43
  transform-origin: top;
48
44
  }
49
45
 
50
46
  .popover[data-placement="bottom"][data-open="true"] {
51
- transform: translateX(-50%) translateY(0) scale(1);
47
+ transform: translateY(0) scale(1);
52
48
  }
53
49
 
54
50
  .popover[data-placement="left"] {
55
- right: calc(100% + var(--popover-offset, 8px));
56
- top: 50%;
57
- transform: translateX(4px) translateY(-50%) scale(0.96);
51
+ transform: translateX(4px) scale(0.96);
58
52
  transform-origin: right;
59
53
  }
60
54
 
61
55
  .popover[data-placement="left"][data-open="true"] {
62
- transform: translateX(0) translateY(-50%) scale(1);
56
+ transform: translateX(0) scale(1);
63
57
  }
64
58
 
65
59
  .popover[data-placement="right"] {
66
- left: calc(100% + var(--popover-offset, 8px));
67
- top: 50%;
68
- transform: translateX(-4px) translateY(-50%) scale(0.96);
60
+ transform: translateX(-4px) scale(0.96);
69
61
  transform-origin: left;
70
62
  }
71
63
 
72
64
  .popover[data-placement="right"][data-open="true"] {
73
- transform: translateX(0) translateY(-50%) scale(1);
65
+ transform: translateX(0) scale(1);
74
66
  }
75
67
 
76
68
  .popover__dialog {
@@ -1,13 +1,15 @@
1
1
  import "./Popover.css";
2
2
  import { type Component, type JSX, type ParentComponent } from "solid-js";
3
3
  import type { IComponentBaseProps } from "../types";
4
- export type PopoverPlacement = "top" | "bottom" | "left" | "right";
4
+ import { type OverlayPlacement } from "../_shared/overlayPosition";
5
+ export type PopoverPlacement = OverlayPlacement;
5
6
  export type PopoverRootProps = IComponentBaseProps & Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> & {
6
7
  children: JSX.Element;
7
8
  isOpen?: boolean;
8
9
  defaultOpen?: boolean;
9
10
  onOpenChange?: (open: boolean) => void;
10
11
  placement?: PopoverPlacement;
12
+ autoFlip?: boolean;
11
13
  offset?: number;
12
14
  closeOnOutsideClick?: boolean;
13
15
  closeOnEscape?: boolean;