@true-engineering/true-react-common-ui-kit 4.0.0-alpha74 → 4.0.0-alpha76

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.
@@ -1,4 +1,4 @@
1
- import { FC, useRef, useState } from 'react';
1
+ import { Dispatch, FC, SetStateAction, useRef, useState } from 'react';
2
2
  import clsx from 'clsx';
3
3
  import {
4
4
  applyAction,
@@ -28,6 +28,8 @@ import {
28
28
  UseFocusProps,
29
29
  UseDismissProps,
30
30
  UseTransitionStatusProps,
31
+ FlipOptions,
32
+ MiddlewareState,
31
33
  } from '@floating-ui/react';
32
34
  import { ICommonProps, IDataAttributes, IRenderNode } from '../../types';
33
35
  import { DEFAULT_OFFSET } from './constants';
@@ -45,6 +47,7 @@ import { useStyles, IWithPopupStyles } from './WithPopup.styles';
45
47
  export interface IWithPopupProps extends ICommonProps<IWithPopupStyles> {
46
48
  trigger: IRenderNode<IWithPopupTriggerProps>;
47
49
  children: IRenderNode<IWithPopupChildrenProps>;
50
+ state?: [boolean, Dispatch<SetStateAction<boolean>>];
48
51
  middlewares?: Middleware[];
49
52
  /** @default eventType === 'click' ? 'bottom-end' : 'top' */
50
53
  placement?: Placement;
@@ -77,6 +80,7 @@ export interface IWithPopupProps extends ICommonProps<IWithPopupStyles> {
77
80
  /** Должна ли минимальная ширина попапа быть равна ширине триггера
78
81
  * @default false */
79
82
  isMinWidthSameAsTrigger?: boolean;
83
+ flipOptions?: FlipOptions | ((state: MiddlewareState) => FlipOptions);
80
84
  hoverOptions?: UseHoverProps;
81
85
  clickOptions?: UseClickProps;
82
86
  focusOptions?: UseFocusProps;
@@ -88,6 +92,7 @@ export interface IWithPopupProps extends ICommonProps<IWithPopupStyles> {
88
92
  export const WithPopup: FC<IWithPopupProps> = ({
89
93
  trigger,
90
94
  children,
95
+ state,
91
96
  middlewares = [],
92
97
  eventType = 'click',
93
98
  placement = eventType === 'click' ? 'bottom-end' : 'top',
@@ -103,6 +108,7 @@ export const WithPopup: FC<IWithPopupProps> = ({
103
108
  isDisabled = false,
104
109
  shouldShowArrow = false,
105
110
  isMinWidthSameAsTrigger = false,
111
+ flipOptions,
106
112
  hoverOptions,
107
113
  clickOptions,
108
114
  focusOptions,
@@ -115,15 +121,18 @@ export const WithPopup: FC<IWithPopupProps> = ({
115
121
  }) => {
116
122
  const classes = useStyles({ theme: tweakStyles });
117
123
 
118
- const [isOpen, setIsOpen] = useState(false);
124
+ const innerState = useState(false);
125
+ const [isOpen, setIsOpen] = state ?? innerState;
119
126
  const isActive = isOpen && !isDisabled;
120
127
 
121
128
  const arrowRef = useRef<SVGSVGElement>(null);
122
129
 
123
130
  const handleToggle = (next: boolean, event?: IWithPopupToggleEvent) => {
124
131
  event?.stopPropagation();
125
- onToggle?.(next, event);
126
- setIsOpen(next);
132
+ if (isOpen !== next) {
133
+ onToggle?.(next, event);
134
+ setIsOpen(next);
135
+ }
127
136
  };
128
137
 
129
138
  const handleClose = (event?: IWithPopupToggleEvent) => {
@@ -134,7 +143,11 @@ export const WithPopup: FC<IWithPopupProps> = ({
134
143
  open: isActive,
135
144
  middleware: [
136
145
  offset(popupOffset),
137
- canBeFlipped && flip({ fallbackAxisSideDirection: 'start' }),
146
+ canBeFlipped &&
147
+ flip((middlewareState) => ({
148
+ fallbackAxisSideDirection: 'start',
149
+ ...applyAction(flipOptions, middlewareState),
150
+ })),
138
151
  isMinWidthSameAsTrigger && minWidthRelativeToTrigger,
139
152
  ...middlewares,
140
153
  shouldShowArrow && arrow({ element: arrowRef }),
@@ -27,20 +27,6 @@ export const getParentNode = (element: Element | ShadowRoot | Document): Element
27
27
  ? (element as Element)
28
28
  : (element.parentNode as Element) ?? (element as ShadowRoot).host;
29
29
 
30
- export const hasExactParent = (element: Element, parent: Element): boolean => {
31
- if (element === parent) {
32
- return true; // Found the exact parent
33
- }
34
-
35
- const parentNode = getParentNode(element);
36
-
37
- if (parentNode === element) {
38
- return false; // Reached the top-level HTML element or Shadow DOM host
39
- }
40
-
41
- return hasExactParent(parentNode, parent);
42
- };
43
-
44
30
  export const getStyleComputedProperty = (element: Element): Partial<CSSStyleDeclaration> =>
45
31
  element.nodeType !== 1 ? {} : getComputedStyle(element, null);
46
32