@synerise/ds-popover 1.1.2 → 1.2.0

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.2.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-popover@1.1.2...@synerise/ds-popover@1.2.0) (2025-12-19)
7
+
8
+ ### Features
9
+
10
+ - **popconfirm:** migrate to popover ([f14f74e](https://github.com/Synerise/synerise-design/commit/f14f74e1f9879ddd8264dc2614723a298b656d2f))
11
+
6
12
  ## [1.1.2](https://github.com/Synerise/synerise-design/compare/@synerise/ds-popover@1.1.1...@synerise/ds-popover@1.1.2) (2025-12-15)
7
13
 
8
14
  **Note:** Version bump only for package @synerise/ds-popover
@@ -1,2 +1,5 @@
1
+ import { type Placement } from '@floating-ui/react';
2
+ import { type LegacyPlacement } from './Popover.types';
1
3
  export declare const HOVER_OPEN_DELAY = 100;
2
4
  export declare const HOVER_CLOSE_DELAY = 100;
5
+ export declare const PLACEMENT_MAP: Record<LegacyPlacement, Placement>;
@@ -1,2 +1,18 @@
1
1
  export var HOVER_OPEN_DELAY = 100;
2
- export var HOVER_CLOSE_DELAY = 100;
2
+ export var HOVER_CLOSE_DELAY = 100;
3
+ export var PLACEMENT_MAP = {
4
+ top: 'top',
5
+ bottom: 'bottom',
6
+ left: 'left',
7
+ right: 'right',
8
+ leftTop: 'left-start',
9
+ leftBottom: 'left-end',
10
+ rightTop: 'right-start',
11
+ rightBottom: 'right-end',
12
+ topRight: 'top-end',
13
+ topLeft: 'top-start',
14
+ topCenter: 'top',
15
+ bottomCenter: 'bottom',
16
+ bottomLeft: 'bottom-start',
17
+ bottomRight: 'bottom-end'
18
+ };
@@ -1,5 +1,5 @@
1
- import { type CSSProperties, type Dispatch, type ReactNode, type SetStateAction } from 'react';
2
- import { type AutoUpdateOptions, type FlipOptions, type OffsetOptions, type OpenChangeReason, type Placement, type ShiftOptions, type UseDismissProps, type UseFloatingReturn, type UseInteractionsReturn, type UseListNavigationProps, type UseTransitionStylesProps } from '@floating-ui/react';
1
+ import { type CSSProperties, type Dispatch, type ReactNode, type RefObject, type SetStateAction } from 'react';
2
+ import { type ArrowOptions, type AutoUpdateOptions, type FlipOptions, type OffsetOptions, type OpenChangeReason, type Placement, type ShiftOptions, type UseDismissProps, type UseFloatingReturn, type UseInteractionsReturn, type UseListNavigationProps, type UseTransitionStylesProps } from '@floating-ui/react';
3
3
  export type PopoverProps = {
4
4
  children: ReactNode;
5
5
  } & PopoverOptions;
@@ -26,6 +26,7 @@ export type PopoverOptions = {
26
26
  offsetConfig?: OffsetConfig;
27
27
  flipConfig?: FlipConfig;
28
28
  shiftConfig?: ShiftConfig;
29
+ arrowConfig?: Omit<ArrowOptions, 'element'>;
29
30
  dismissConfig?: UseDismissProps;
30
31
  listNavigationConfig?: UseListNavigationProps;
31
32
  trigger?: PopoverTriggerType | PopoverTriggerType[];
@@ -56,5 +57,9 @@ export type UsePopoverReturn = Omit<UseFloatingReturn, 'open'> & UseInteractions
56
57
  zIndex?: number;
57
58
  returnFocus?: boolean;
58
59
  componentId?: string;
60
+ arrowRef: RefObject<HTMLElement>;
59
61
  };
62
+ export type LegacyDropdownPlacement = Exclude<LegacyPlacement, 'right' | 'left' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom'>;
63
+ export type LegacyPopconfirmPlacement = LegacyPlacement;
64
+ export type LegacyPlacement = 'topLeft' | 'top' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottom' | 'bottomCenter' | 'bottomRight' | 'right' | 'left' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
60
65
  export {};
@@ -0,0 +1,6 @@
1
+ import { type ReactElement } from 'react';
2
+ import { type Placement } from '@floating-ui/react';
3
+ export declare const PopoverArrow: ({ children, getClassNameFromPlacement, }: {
4
+ children?: ReactElement;
5
+ getClassNameFromPlacement?: (placement: Placement) => string;
6
+ }) => ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
@@ -0,0 +1,31 @@
1
+ import classNames from 'classnames';
2
+ import { cloneElement, isValidElement } from 'react';
3
+ import { useTheme } from '@synerise/ds-core';
4
+ import { usePopoverContext } from '../hooks';
5
+ export var PopoverArrow = function PopoverArrow(_ref) {
6
+ var children = _ref.children,
7
+ getClassNameFromPlacement = _ref.getClassNameFromPlacement;
8
+ var theme = useTheme();
9
+ var _usePopoverContext = usePopoverContext(),
10
+ arrowRef = _usePopoverContext.arrowRef,
11
+ placement = _usePopoverContext.placement,
12
+ zIndex = _usePopoverContext.zIndex,
13
+ middlewareData = _usePopoverContext.middlewareData;
14
+ var placementClassName = (getClassNameFromPlacement == null ? void 0 : getClassNameFromPlacement(placement)) || "ds-popover-arrow-" + placement;
15
+ if (/*#__PURE__*/isValidElement(children)) {
16
+ var _children$props, _middlewareData$arrow, _middlewareData$arrow2;
17
+ return /*#__PURE__*/cloneElement(children, {
18
+ // @ts-expect-error ref unknown
19
+ ref: arrowRef,
20
+ // @ts-expect-error props.className may not exist
21
+ className: classNames(placementClassName, (_children$props = children.props) == null ? void 0 : _children$props.className),
22
+ style: {
23
+ zIndex: zIndex !== undefined ? "" + zIndex : theme.variables['zindex-dropdown'],
24
+ position: 'absolute',
25
+ left: (_middlewareData$arrow = middlewareData.arrow) == null ? void 0 : _middlewareData$arrow.x,
26
+ top: (_middlewareData$arrow2 = middlewareData.arrow) == null ? void 0 : _middlewareData$arrow2.y
27
+ }
28
+ });
29
+ }
30
+ return children;
31
+ };
@@ -5,6 +5,7 @@ import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { FloatingFocusManager, FloatingPortal, useMergeRefs } from '@floating-ui/react';
6
6
  import { useTheme } from '@synerise/ds-core';
7
7
  import { usePopoverContext } from '../hooks/usePopoverContext';
8
+ import { GlobalStyles } from './PopoverContent.styles';
8
9
  export var PopoverContent = /*#__PURE__*/forwardRef(function PopoverContent(_ref, propRef) {
9
10
  var style = _ref.style,
10
11
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
@@ -54,7 +55,7 @@ export var PopoverContent = /*#__PURE__*/forwardRef(function PopoverContent(_ref
54
55
  }
55
56
  return /*#__PURE__*/React.createElement(FloatingPortal, {
56
57
  root: getPopupContainer ? popupContainerRef : undefined
57
- }, /*#__PURE__*/React.createElement(FloatingFocusManager, {
58
+ }, /*#__PURE__*/React.createElement(GlobalStyles, null), /*#__PURE__*/React.createElement(FloatingFocusManager, {
58
59
  initialFocus: -1,
59
60
  context: floatingContext,
60
61
  modal: modal,
@@ -0,0 +1 @@
1
+ export declare const GlobalStyles: import("styled-components").GlobalStyleComponent<{}, import("styled-components").DefaultTheme>;
@@ -0,0 +1,2 @@
1
+ import { createGlobalStyle } from 'styled-components';
2
+ export var GlobalStyles = createGlobalStyle(["[data-popover-trigger] ~ span[aria-hidden],div[data-floating-ui-portal]{display:contents;}"]);
@@ -13,11 +13,13 @@ export var PopoverTrigger = /*#__PURE__*/forwardRef(function (_ref, propRef) {
13
13
  var context = usePopoverContext();
14
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
15
  var childrenRef = children.ref;
16
- var ref = useMergeRefs([context.refs.setReference, propRef, childrenRef]);
16
+ var renderAsChild = asChild && /*#__PURE__*/isValidElement(children);
17
+ var refsArray = [propRef, childrenRef, !renderAsChild && context.refs.setReference];
18
+ var ref = useMergeRefs(refsArray.filter(Boolean));
17
19
  // `asChild` allows the user to pass any element as the anchor
18
20
  // if the child is a component it needs to forward the ref to a html element
19
21
  // so that the Popover can position itself correctly.
20
- if (asChild && /*#__PURE__*/isValidElement(children)) {
22
+ if (renderAsChild) {
21
23
  var referenceProps = context.getReferenceProps(_extends({
22
24
  ref: ref,
23
25
  'data-popover-trigger': true,
@@ -25,7 +27,13 @@ export var PopoverTrigger = /*#__PURE__*/forwardRef(function (_ref, propRef) {
25
27
  }, props, children.props, {
26
28
  'data-state': context.open ? 'open' : 'closed'
27
29
  }));
28
- return /*#__PURE__*/cloneElement(children, _extends({}, referenceProps));
30
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(S.TriggerAnchor, {
31
+ "aria-hidden": "true",
32
+ hidden: true,
33
+ ref: function ref(node) {
34
+ context.refs.setReference((node == null ? void 0 : node.nextElementSibling) || null);
35
+ }
36
+ }), /*#__PURE__*/cloneElement(children, _extends({}, referenceProps)));
29
37
  }
30
38
  return /*#__PURE__*/React.createElement(S.Trigger, _extends({
31
39
  ref: ref
@@ -1 +1,2 @@
1
1
  export declare const Trigger: import("styled-components").StyledComponent<"span", any, {}, never>;
2
+ export declare const TriggerAnchor: import("styled-components").StyledComponent<"span", any, {}, never>;
@@ -2,4 +2,8 @@ import styled from 'styled-components';
2
2
  export var Trigger = styled.span.withConfig({
3
3
  displayName: "PopoverTriggerstyles__Trigger",
4
4
  componentId: "sc-1irht31-0"
5
- })(["display:flex;"]);
5
+ })(["display:flex;"]);
6
+ export var TriggerAnchor = styled.span.withConfig({
7
+ displayName: "PopoverTriggerstyles__TriggerAnchor",
8
+ componentId: "sc-1irht31-1"
9
+ })(["display:contents !important;"]);
@@ -1,3 +1,4 @@
1
1
  export * from './PopoverTrigger';
2
2
  export * from './PopoverClose';
3
3
  export * from './PopoverContent';
4
+ export * from './PopoverArrow';
@@ -1,3 +1,4 @@
1
1
  export * from './PopoverTrigger';
2
2
  export * from './PopoverClose';
3
- export * from './PopoverContent';
3
+ export * from './PopoverContent';
4
+ export * from './PopoverArrow';
@@ -1,2 +1,2 @@
1
1
  import { type PopoverOptions, type UsePopoverReturn } from '../Popover.types';
2
- export declare const usePopover: ({ initialOpen, placement, modal, trigger, open: controlledOpen, onOpenChange: setControlledOpen, onDismiss, transitionDuration, getPopupContainer, autoUpdate: autoUpdateWhileMounted, dismissConfig, offsetConfig, flipConfig, shiftConfig, testId, componentId, returnFocus, listNavigationConfig, getTransitionConfig, zIndex, }?: PopoverOptions) => UsePopoverReturn;
2
+ export declare const usePopover: ({ initialOpen, placement, modal, trigger, open: controlledOpen, onOpenChange: setControlledOpen, onDismiss, transitionDuration, getPopupContainer, autoUpdate: autoUpdateWhileMounted, dismissConfig, offsetConfig, flipConfig, shiftConfig, arrowConfig, testId, componentId, returnFocus, listNavigationConfig, getTransitionConfig, zIndex, }?: PopoverOptions) => UsePopoverReturn;
@@ -1,5 +1,5 @@
1
1
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
- import { useMemo, useState } from 'react';
2
+ import { useMemo, useRef, useState } from 'react';
3
3
  import { autoUpdate, useClick, useDismiss, useFloating, useHover, useInteractions, useListNavigation, useRole, useTransitionStyles } from '@floating-ui/react';
4
4
  import { HOVER_CLOSE_DELAY, HOVER_OPEN_DELAY } from '../Popover.const';
5
5
  import { getDefaultTransitionConfig, getMiddleware } from '../utils';
@@ -27,6 +27,8 @@ export var usePopover = function usePopover(_temp) {
27
27
  flipConfig = _ref$flipConfig === void 0 ? {} : _ref$flipConfig,
28
28
  _ref$shiftConfig = _ref.shiftConfig,
29
29
  shiftConfig = _ref$shiftConfig === void 0 ? {} : _ref$shiftConfig,
30
+ _ref$arrowConfig = _ref.arrowConfig,
31
+ arrowConfig = _ref$arrowConfig === void 0 ? {} : _ref$arrowConfig,
30
32
  _ref$testId = _ref.testId,
31
33
  testId = _ref$testId === void 0 ? 'noTestId' : _ref$testId,
32
34
  componentId = _ref.componentId,
@@ -46,6 +48,7 @@ export var usePopover = function usePopover(_temp) {
46
48
  setDescriptionId = _useState3[1];
47
49
  var open = controlledOpen != null ? controlledOpen : uncontrolledOpen;
48
50
  var setOpen = setControlledOpen != null ? setControlledOpen : setUncontrolledOpen;
51
+ var arrowRef = useRef(null);
49
52
  var triggerArray = Array.isArray(trigger) ? trigger : [trigger];
50
53
  var whileElementsMounted = useMemo(function () {
51
54
  if (!autoUpdateWhileMounted) {
@@ -72,7 +75,10 @@ export var usePopover = function usePopover(_temp) {
72
75
  middleware: getMiddleware({
73
76
  offsetConfig: offsetConfig,
74
77
  flipConfig: flipConfig,
75
- shiftConfig: shiftConfig
78
+ shiftConfig: shiftConfig,
79
+ arrowConfig: _extends({}, arrowConfig, {
80
+ element: arrowRef.current
81
+ })
76
82
  })
77
83
  });
78
84
  var context = data.context;
@@ -113,7 +119,8 @@ export var usePopover = function usePopover(_temp) {
113
119
  testId: testId,
114
120
  zIndex: zIndex,
115
121
  returnFocus: returnFocus,
116
- componentId: componentId
122
+ componentId: componentId,
123
+ arrowRef: arrowRef
117
124
  });
118
125
  }, [getPopupContainer, isMounted, setOpen, transitionDuration, styles, interactions, data, modal, labelId, descriptionId, zIndex, testId, returnFocus, componentId]);
119
126
  };
package/dist/index.d.ts CHANGED
@@ -2,3 +2,5 @@ export * from './Popover';
2
2
  export * from './components';
3
3
  export { Popover as default } from './Popover';
4
4
  export * from './Popover.types';
5
+ export { getPlacement } from './utils/getPlacement';
6
+ export { PLACEMENT_MAP } from './Popover.const';
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from './Popover';
2
2
  export * from './components';
3
3
  export { Popover as default } from './Popover';
4
- export * from './Popover.types';
4
+ export * from './Popover.types';
5
+ export { getPlacement } from './utils/getPlacement';
6
+ export { PLACEMENT_MAP } from './Popover.const';
@@ -1,10 +1,12 @@
1
+ import { type ArrowOptions } from '@floating-ui/react';
1
2
  import { type FlipConfig, type OffsetConfig, type ShiftConfig } from '../Popover.types';
2
3
  type GetMiddleware = {
3
4
  offsetConfig: OffsetConfig;
4
5
  flipConfig: FlipConfig;
5
6
  shiftConfig: ShiftConfig;
7
+ arrowConfig?: ArrowOptions;
6
8
  };
7
- export declare const getMiddleware: ({ offsetConfig, flipConfig, shiftConfig, }: GetMiddleware) => {
9
+ export declare const getMiddleware: ({ offsetConfig, flipConfig, shiftConfig, arrowConfig, }: GetMiddleware) => {
8
10
  name: string;
9
11
  options?: any;
10
12
  fn: (state: import("@floating-ui/react").MiddlewareState) => import("@floating-ui/react").MiddlewareReturn | Promise<import("@floating-ui/react").MiddlewareReturn>;
@@ -2,11 +2,12 @@ var _excluded = ["enabled"],
2
2
  _excluded2 = ["enabled"],
3
3
  _excluded3 = ["enabled"];
4
4
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
5
- import { flip, offset, shift } from '@floating-ui/react';
5
+ import { arrow, flip, offset, shift } from '@floating-ui/react';
6
6
  export var getMiddleware = function getMiddleware(_ref) {
7
7
  var offsetConfig = _ref.offsetConfig,
8
8
  flipConfig = _ref.flipConfig,
9
- shiftConfig = _ref.shiftConfig;
9
+ shiftConfig = _ref.shiftConfig,
10
+ arrowConfig = _ref.arrowConfig;
10
11
  var middleware = [];
11
12
  var _ref2 = offsetConfig || {},
12
13
  _ref2$enabled = _ref2.enabled,
@@ -29,5 +30,8 @@ export var getMiddleware = function getMiddleware(_ref) {
29
30
  if (shiftEnabled) {
30
31
  middleware.push(shift(shiftOptions));
31
32
  }
33
+ if (arrowConfig != null && arrowConfig.element) {
34
+ middleware.push(arrow(arrowConfig));
35
+ }
32
36
  return middleware;
33
37
  };
@@ -0,0 +1,3 @@
1
+ import { type Placement } from '@floating-ui/react';
2
+ import { type LegacyPlacement } from '../Popover.types';
3
+ export declare const getPlacement: (placement: LegacyPlacement) => Placement;
@@ -0,0 +1,4 @@
1
+ import { PLACEMENT_MAP } from '../Popover.const';
2
+ export var getPlacement = function getPlacement(placement) {
3
+ return PLACEMENT_MAP[placement];
4
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-popover",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Popover UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -34,14 +34,16 @@
34
34
  ],
35
35
  "types": "dist/index.d.ts",
36
36
  "dependencies": {
37
- "@floating-ui/react": "^0.27.16"
37
+ "@floating-ui/react": "^0.27.16",
38
+ "classnames": "^2.5.1"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@testing-library/user-event": "^14"
41
42
  },
42
43
  "peerDependencies": {
43
44
  "@synerise/ds-core": "*",
44
- "react": ">=16.9.0 <= 18.3.1"
45
+ "react": ">=16.9.0 <= 18.3.1",
46
+ "styled-components": "^5.3.3"
45
47
  },
46
- "gitHead": "b1279d5354132a2bf0b6f0cfa343db4c6c928f72"
48
+ "gitHead": "c638fc7e1af8aea55d466a643329fe499b2b3383"
47
49
  }