@inceptionbg/iui 2.0.24 → 2.0.26

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.
Files changed (208) hide show
  1. package/dist/NoAccessPage-DTPU8bP2.js +2 -0
  2. package/dist/{NoAccessPage-CJisyKrk.js.map → NoAccessPage-DTPU8bP2.js.map} +1 -1
  3. package/dist/NotFoundPage-PZunMooy.js +2 -0
  4. package/dist/{NotFoundPage-BeRit0kr.js.map → NotFoundPage-PZunMooy.js.map} +1 -1
  5. package/dist/icons/index.d.ts +3 -1
  6. package/dist/icons/index.js +1 -1
  7. package/dist/index.d.ts +44 -31
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/iui.css +1 -1
  11. package/package.json +1 -1
  12. package/src/assets/icons/duotone/faBell.ts +17 -17
  13. package/src/assets/icons/duotone/faCircleUser.ts +17 -17
  14. package/src/assets/icons/index.ts +26 -25
  15. package/src/assets/icons/light/faArrowDownShortWide.ts +15 -15
  16. package/src/assets/icons/light/faArrowDownWideShort.ts +15 -15
  17. package/src/assets/icons/light/faArrowLeft.ts +15 -15
  18. package/src/assets/icons/light/faArrowRight.ts +15 -15
  19. package/src/assets/icons/light/faArrowUpArrowDown.ts +15 -15
  20. package/src/assets/icons/light/faArrowUpRightFromSquare.ts +15 -15
  21. package/src/assets/icons/light/faArrowsToLine.ts +15 -15
  22. package/src/assets/icons/light/faArrowsUpDown.ts +15 -15
  23. package/src/assets/icons/light/faBell.ts +15 -15
  24. package/src/assets/icons/light/faBookmark.ts +15 -15
  25. package/src/assets/icons/light/faBookmarkSlash.ts +15 -15
  26. package/src/assets/icons/light/faCalendarPlus.ts +15 -15
  27. package/src/assets/icons/light/faCheck.ts +15 -15
  28. package/src/assets/icons/light/faChevronDown.ts +15 -15
  29. package/src/assets/icons/light/faChevronRight.ts +15 -15
  30. package/src/assets/icons/light/faCircleCheck.ts +15 -0
  31. package/src/assets/icons/light/faCircleInfo.ts +15 -15
  32. package/src/assets/icons/light/faCircleXmark.ts +15 -15
  33. package/src/assets/icons/light/faClipboardCheck.ts +15 -15
  34. package/src/assets/icons/light/faClockRotateLeft.ts +15 -15
  35. package/src/assets/icons/light/faEllipsisVertical.ts +15 -15
  36. package/src/assets/icons/light/faEnvelope.ts +15 -15
  37. package/src/assets/icons/light/faEye.ts +15 -15
  38. package/src/assets/icons/light/faEyeSlash.ts +15 -15
  39. package/src/assets/icons/light/faFilter.ts +15 -15
  40. package/src/assets/icons/light/faGear.ts +15 -15
  41. package/src/assets/icons/light/faHouse.ts +15 -15
  42. package/src/assets/icons/light/faIdBadge.ts +15 -15
  43. package/src/assets/icons/light/faLineColumns.ts +15 -15
  44. package/src/assets/icons/light/faLink.ts +15 -15
  45. package/src/assets/icons/light/faMagnifyingGlass.ts +15 -15
  46. package/src/assets/icons/light/faPen.ts +15 -15
  47. package/src/assets/icons/light/faPrint.ts +15 -15
  48. package/src/assets/icons/light/faQuestion.ts +15 -15
  49. package/src/assets/icons/light/faRotateRight.ts +15 -15
  50. package/src/assets/icons/light/faTrashCan.ts +15 -15
  51. package/src/assets/icons/light/faTriangleExclamation.ts +15 -15
  52. package/src/assets/icons/light/faXmark.ts +15 -15
  53. package/src/assets/icons/regular/faArrowLeft.ts +15 -15
  54. package/src/assets/icons/regular/faArrowRightArrowLeft.ts +15 -15
  55. package/src/assets/icons/regular/faCircleCheck.ts +15 -15
  56. package/src/assets/icons/regular/faCircleExclamation.ts +15 -15
  57. package/src/assets/icons/regular/faCircleInfo.ts +15 -15
  58. package/src/assets/icons/regular/faFileArrowDown.ts +15 -15
  59. package/src/assets/icons/regular/faFilterCircleXmark.ts +15 -15
  60. package/src/assets/icons/regular/faTriangleExclamation.ts +15 -15
  61. package/src/assets/icons/solid/faAngleLeft.ts +15 -15
  62. package/src/assets/icons/solid/faAngleRight.ts +15 -15
  63. package/src/assets/icons/solid/faArrowDownWideShort.ts +15 -15
  64. package/src/assets/icons/solid/faCaretDown.ts +15 -15
  65. package/src/assets/icons/solid/faCheck.ts +15 -15
  66. package/src/assets/icons/solid/faEllipsisVertical.ts +15 -15
  67. package/src/assets/icons/solid/faEnvelopeDot.ts +15 -15
  68. package/src/assets/icons/solid/faFilter.ts +15 -15
  69. package/src/assets/icons/solid/faFloppyDisk.ts +15 -15
  70. package/src/assets/icons/solid/faGripDotsVertical.ts +15 -15
  71. package/src/assets/icons/solid/faListUl.ts +15 -15
  72. package/src/assets/icons/solid/faMinus.ts +15 -15
  73. package/src/assets/icons/solid/faPlus.ts +15 -15
  74. package/src/assets/icons/solid/faPrint.ts +15 -15
  75. package/src/assets/icons/solid/faRotateRight.ts +15 -15
  76. package/src/assets/icons/solid/faXmark.ts +15 -15
  77. package/src/components/Accordions/Accordions.tsx +75 -75
  78. package/src/components/Alert/Alert.tsx +31 -31
  79. package/src/components/Badge/DotBadge.tsx +16 -16
  80. package/src/components/Badge/NotificationBadge.tsx +29 -29
  81. package/src/components/Badge/PillBadge.tsx +13 -13
  82. package/src/components/Button/Button.tsx +56 -56
  83. package/src/components/Button/IconButton.tsx +51 -51
  84. package/src/components/Button/SplitButton.tsx +91 -91
  85. package/src/components/Dashboard/Dashboard.tsx +9 -9
  86. package/src/components/Dashboard/DashboardWidget.tsx +44 -44
  87. package/src/components/Dashboard/FastLinksWidget/FastLinksWidget.tsx +37 -37
  88. package/src/components/Dialog/Dialog.tsx +166 -166
  89. package/src/components/Dialog/components/DialogFooter.tsx +100 -100
  90. package/src/components/Header/Components/EnvBadge.tsx +17 -17
  91. package/src/components/Header/Components/ModuleSelect.tsx +68 -68
  92. package/src/components/Header/Components/Notifications.tsx +202 -202
  93. package/src/components/Header/Components/UserMenu.tsx +52 -52
  94. package/src/components/Header/Header.tsx +45 -37
  95. package/src/components/Helper/Collapse.tsx +53 -53
  96. package/src/components/Inputs/Checkbox.tsx +53 -53
  97. package/src/components/Inputs/CurrencyInput.tsx +124 -124
  98. package/src/components/Inputs/DateInput/DateInput.tsx +184 -184
  99. package/src/components/Inputs/DateInput/components/DatePartInput.tsx +159 -159
  100. package/src/components/Inputs/InputWrapper.tsx +95 -95
  101. package/src/components/Inputs/NumberInput.tsx +86 -86
  102. package/src/components/Inputs/PasswordInput.tsx +40 -40
  103. package/src/components/Inputs/PhoneInput/PhoneInput.tsx +108 -108
  104. package/src/components/Inputs/PhoneInput/utils/countryCode.ts +20 -20
  105. package/src/components/Inputs/Radio.tsx +59 -59
  106. package/src/components/Inputs/RadioGroup.tsx +48 -48
  107. package/src/components/Inputs/RadioLarge.tsx +39 -39
  108. package/src/components/Inputs/SearchInput.tsx +46 -46
  109. package/src/components/Inputs/Selects/Select.tsx +17 -17
  110. package/src/components/Inputs/Selects/components/CustomSelectComponents.tsx +19 -20
  111. package/src/components/Inputs/Selects/components/SelectWrapper.tsx +118 -118
  112. package/src/components/Inputs/Selects/utils/selectStyles.ts +101 -101
  113. package/src/components/Inputs/TextAreaInput.tsx +68 -68
  114. package/src/components/Inputs/TextInput.tsx +100 -100
  115. package/src/components/Inputs/TimeInput/TimeInput.tsx +81 -81
  116. package/src/components/List/List.tsx +21 -21
  117. package/src/components/List/ListItem.tsx +70 -70
  118. package/src/components/Loader/Loader.tsx +59 -59
  119. package/src/components/Loader/ProgressBar.tsx +41 -41
  120. package/src/components/Menu/Menu.tsx +81 -81
  121. package/src/components/Menu/MenuItem.tsx +46 -46
  122. package/src/components/Menu/NewMenu.tsx +63 -63
  123. package/src/components/Menu/hooks/useMenuPosition.tsx +116 -116
  124. package/src/components/PageComponents/ScrollableContent.tsx +11 -0
  125. package/src/components/Pullover/Pullover.tsx +197 -197
  126. package/src/components/Router/Router.tsx +52 -52
  127. package/src/components/Sidebar/AddButton.tsx +22 -22
  128. package/src/components/Sidebar/Sidebar.tsx +85 -85
  129. package/src/components/Sidebar/SidebarItem.tsx +84 -84
  130. package/src/components/Sidebar/types/ISidebar.ts +28 -28
  131. package/src/components/Table/Table.tsx +259 -259
  132. package/src/components/Table/components/columns/ColumnsList.tsx +60 -60
  133. package/src/components/Table/components/columns/TableColumnsEdit.tsx +114 -114
  134. package/src/components/Table/components/edit/TableEditRow.tsx +78 -78
  135. package/src/components/Table/components/filters/FilterItem.tsx +15 -15
  136. package/src/components/Table/components/filters/TableFilters.tsx +126 -126
  137. package/src/components/Table/components/footer/TableFooter.tsx +126 -126
  138. package/src/components/Table/components/header/TableHeader.tsx +40 -40
  139. package/src/components/Table/components/header/TableHeaderRow.tsx +57 -57
  140. package/src/components/Table/components/items/TableItemActions.tsx +78 -78
  141. package/src/components/Table/components/print/TablePrint.tsx +200 -200
  142. package/src/components/Table/components/select/TableSelect.tsx +50 -50
  143. package/src/components/Table/components/sort/TableSort.tsx +73 -73
  144. package/src/components/Table/components/templates/CreateTemplateDialog.tsx +58 -58
  145. package/src/components/Table/components/templates/TableTemplates.tsx +65 -65
  146. package/src/components/Table/components/templates/TemplatesPullover.tsx +88 -88
  147. package/src/components/Table/contexts/TableContext.tsx +116 -116
  148. package/src/components/Table/hooks/localHooks/useLocalTableColumns.tsx +70 -70
  149. package/src/components/Table/hooks/localHooks/useLocalTableData.tsx +84 -84
  150. package/src/components/Table/hooks/localHooks/useLocalTableKeyboard.ts +176 -176
  151. package/src/components/Table/hooks/localHooks/useLocalTablePagination.ts +12 -12
  152. package/src/components/Table/hooks/useTableColumns.ts +34 -34
  153. package/src/components/Table/hooks/useTableEdit.tsx +140 -140
  154. package/src/components/Table/hooks/useTableFilterFields.tsx +150 -150
  155. package/src/components/Table/hooks/useTablePagination.ts +19 -19
  156. package/src/components/Table/hooks/useTablePrint.ts +83 -83
  157. package/src/components/Table/hooks/useTableSearch.ts +31 -31
  158. package/src/components/Table/hooks/useTableSelect.ts +19 -19
  159. package/src/components/Table/hooks/useTableSort.ts +8 -8
  160. package/src/components/Tabs/Tabs.tsx +68 -68
  161. package/src/components/Tooltip/Tooltip.tsx +191 -191
  162. package/src/components/Tree/Tree.tsx +22 -22
  163. package/src/components/Tree/TreeItem.tsx +57 -57
  164. package/src/components/Wrappers/AppLayout.tsx +17 -17
  165. package/src/components/Wrappers/ConditionalWrapper.tsx +10 -10
  166. package/src/components/Wrappers/FormWrapper.tsx +84 -84
  167. package/src/components/Wrappers/PageLayout.tsx +164 -156
  168. package/src/hooks/useBackgroundClose.ts +19 -19
  169. package/src/hooks/useGetFocusableElements.ts +43 -43
  170. package/src/hooks/useIsMenuOpen.ts +11 -11
  171. package/src/hooks/useLocalPopoverControl.ts +32 -32
  172. package/src/hooks/usePopupControl.ts +22 -22
  173. package/src/hooks/useZendesk.ts +21 -21
  174. package/src/index.ts +381 -379
  175. package/src/pages/NoAccessPage.tsx +27 -27
  176. package/src/pages/NotFoundPage.tsx +26 -26
  177. package/src/styles/common/helpers/_color.scss +3 -0
  178. package/src/styles/components/_page.scss +0 -13
  179. package/src/types/IBasic.ts +32 -32
  180. package/src/types/IHeader.ts +40 -40
  181. package/src/types/IInfo.ts +1 -1
  182. package/src/types/IKeyboard.ts +33 -33
  183. package/src/types/IMenu.ts +19 -19
  184. package/src/types/INotifications.ts +15 -15
  185. package/src/types/IPopup.ts +17 -17
  186. package/src/types/IRouter.ts +6 -6
  187. package/src/types/ISelect.ts +54 -54
  188. package/src/types/ITab.ts +10 -10
  189. package/src/types/ITable.ts +290 -290
  190. package/src/utils/InputPatternValidation.ts +12 -12
  191. package/src/utils/dateUtils.ts +32 -32
  192. package/src/utils/fileUtils.ts +177 -177
  193. package/src/utils/i18n/i18nIUICyrilic.ts +119 -119
  194. package/src/utils/i18n/i18nIUILatin.ts +120 -120
  195. package/src/utils/i18n/i18nIUIMe.ts +118 -118
  196. package/src/utils/icons.ts +13 -13
  197. package/src/utils/localStorageHelper.ts +24 -24
  198. package/src/utils/logoUtils.ts +7 -7
  199. package/src/utils/numberUtils.ts +21 -21
  200. package/src/utils/objectUtils.ts +114 -114
  201. package/src/utils/popupUtils.ts +82 -82
  202. package/src/utils/rootDir.ts +1 -1
  203. package/src/utils/stringUtils.ts +18 -18
  204. package/src/utils/tableUtils.ts +130 -130
  205. package/src/utils/toasts.ts +6 -6
  206. package/src/utils/urlUtils.ts +4 -4
  207. package/dist/NoAccessPage-CJisyKrk.js +0 -2
  208. package/dist/NotFoundPage-BeRit0kr.js +0 -2
@@ -1,191 +1,191 @@
1
- import type { Dispatch, FC, ReactElement, Ref, SetStateAction } from 'react';
2
- import { cloneElement, useEffect, useRef, useState } from 'react';
3
- import clsx from 'clsx';
4
- import { createPortal } from 'react-dom';
5
- import { rootDir } from '../../utils/rootDir';
6
-
7
- export type TooltipPosition = 'left' | 'right' | 'top' | 'bottom';
8
-
9
- interface Props {
10
- label?: string;
11
- position?: TooltipPosition;
12
- disabled?: boolean;
13
- singleLine?: boolean;
14
- className?: string;
15
- children: ReactElement;
16
- ref?: Ref<HTMLElement> | null;
17
- }
18
-
19
- export const Tooltip: FC<Props> = ({
20
- label,
21
- position = 'top',
22
- disabled,
23
- singleLine,
24
- className,
25
- children,
26
- ref,
27
- }) => {
28
- const [newPosition, setNewPosition] = useState<TooltipPosition | ''>('');
29
-
30
- const internalRef = useRef<HTMLElement>(null);
31
- const tooltipRef = useRef<HTMLDivElement>(null);
32
-
33
- useEffect(() => {
34
- if (!disabled && !!label) {
35
- const getContainer = () => {
36
- if (ref && 'current' in ref) {
37
- return ref.current;
38
- }
39
- return internalRef.current;
40
- };
41
-
42
- const container = getContainer();
43
- const tooltip = tooltipRef.current;
44
-
45
- const onMouseEnter = () => {
46
- if (container && tooltip) {
47
- setAbsolutePosition(container, tooltip, position, setNewPosition);
48
- tooltip.classList.add('visible');
49
- }
50
- };
51
- const onMouseLeave = () => tooltip?.classList.remove('visible');
52
-
53
- if (container) {
54
- container.addEventListener('mouseenter', onMouseEnter);
55
- container.addEventListener('mouseleave', onMouseLeave);
56
-
57
- return () => {
58
- container.removeEventListener('mouseenter', onMouseEnter);
59
- container.removeEventListener('mouseleave', onMouseLeave);
60
- };
61
- }
62
- }
63
- }, [disabled, label, position, ref]);
64
-
65
- return !!label && !disabled ? (
66
- <>
67
- {/* @ts-ignore */}
68
- {cloneElement(children, { ref: ref || internalRef })}
69
- {createPortal(
70
- <div
71
- ref={tooltipRef}
72
- className={clsx('tooltip-container', className, {
73
- 'no-wrap': singleLine,
74
- })}
75
- >
76
- <div className="tooltip">
77
- <div className={clsx('arrow', newPosition || position)} />
78
- <div>{label}</div>
79
- </div>
80
- </div>,
81
- rootDir
82
- )}
83
- </>
84
- ) : (
85
- children
86
- );
87
- };
88
-
89
- const setAbsolutePosition = (
90
- containerEl: HTMLElement,
91
- targetEl: HTMLDivElement,
92
- position: TooltipPosition,
93
- setNewPosition: Dispatch<SetStateAction<TooltipPosition | ''>>
94
- ) => {
95
- const containerRect = containerEl.getBoundingClientRect();
96
- const tooltipRect = targetEl.getBoundingClientRect();
97
- const margin = 16; // Distance from container
98
- const screenPadding = 8; // Minimum distance from screen edges
99
-
100
- if (position === 'bottom' || position === 'top') {
101
- const bottom = Math.floor(containerRect.bottom + margin);
102
- const top = Math.floor(containerRect.top - tooltipRect.height - margin);
103
- let leftCenter = Math.floor(
104
- containerRect.left + containerRect.width / 2 - tooltipRect.width / 2
105
- );
106
-
107
- // Check if tooltip overflows horizontally and adjust
108
- if (leftCenter < screenPadding) {
109
- targetEl.style.width = `${tooltipRect.width + leftCenter}px`;
110
- leftCenter = screenPadding;
111
- } else if (leftCenter + tooltipRect.width > window.innerWidth - screenPadding) {
112
- leftCenter = window.innerWidth - tooltipRect.width - screenPadding;
113
- }
114
-
115
- const reverse =
116
- position === 'top' ? top < 0 : bottom + tooltipRect.height > window.innerHeight;
117
-
118
- setNewPosition(reverse ? (position === 'bottom' ? 'top' : 'bottom') : '');
119
-
120
- let finalTop =
121
- position === 'bottom' ? (reverse ? top : bottom) : reverse ? bottom : top;
122
-
123
- // Ensure tooltip doesn't go above screen
124
- if (finalTop < screenPadding) {
125
- finalTop = screenPadding;
126
- }
127
- // Ensure tooltip doesn't go below screen
128
- if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
129
- finalTop = window.innerHeight - tooltipRect.height - screenPadding;
130
- }
131
-
132
- targetEl.style.top = `${finalTop}px`;
133
- targetEl.style.left = `${leftCenter}px`;
134
- } else if (position === 'right') {
135
- let finalTop = Math.floor(
136
- containerRect.top + containerRect.height / 2 - tooltipRect.height / 2
137
- );
138
- let finalLeft = Math.floor(containerRect.right + margin);
139
-
140
- // Check if tooltip overflows vertically and adjust
141
- if (finalTop < screenPadding) {
142
- finalTop = screenPadding;
143
- } else if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
144
- finalTop = window.innerHeight - tooltipRect.height - screenPadding;
145
- }
146
-
147
- // Check if tooltip overflows to the right and flip to left
148
- if (finalLeft + tooltipRect.width > window.innerWidth - screenPadding) {
149
- finalLeft = Math.floor(containerRect.left - tooltipRect.width - margin);
150
- setNewPosition('left');
151
-
152
- // If it still overflows on the left, position it at the edge
153
- if (finalLeft < screenPadding) {
154
- finalLeft = screenPadding;
155
- }
156
- } else {
157
- setNewPosition('');
158
- }
159
-
160
- targetEl.style.top = `${finalTop}px`;
161
- targetEl.style.left = `${finalLeft}px`;
162
- } else if (position === 'left') {
163
- let finalTop = Math.floor(
164
- containerRect.top + containerRect.height / 2 - tooltipRect.height / 2
165
- );
166
- let finalLeft = Math.floor(containerRect.left - tooltipRect.width - margin);
167
-
168
- // Check if tooltip overflows vertically and adjust
169
- if (finalTop < screenPadding) {
170
- finalTop = screenPadding;
171
- } else if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
172
- finalTop = window.innerHeight - tooltipRect.height - screenPadding;
173
- }
174
-
175
- // Check if tooltip overflows to the left and flip to right
176
- if (finalLeft < screenPadding) {
177
- finalLeft = Math.floor(containerRect.right + margin);
178
- setNewPosition('right');
179
-
180
- // If it still overflows on the right, position it at the edge
181
- if (finalLeft + tooltipRect.width > window.innerWidth - screenPadding) {
182
- finalLeft = window.innerWidth - tooltipRect.width - screenPadding;
183
- }
184
- } else {
185
- setNewPosition('');
186
- }
187
-
188
- targetEl.style.top = `${finalTop}px`;
189
- targetEl.style.left = `${finalLeft}px`;
190
- }
191
- };
1
+ import type { Dispatch, FC, ReactElement, Ref, SetStateAction } from 'react';
2
+ import { cloneElement, useEffect, useRef, useState } from 'react';
3
+ import clsx from 'clsx';
4
+ import { createPortal } from 'react-dom';
5
+ import { rootDir } from '../../utils/rootDir';
6
+
7
+ export type TooltipPosition = 'left' | 'right' | 'top' | 'bottom';
8
+
9
+ interface Props {
10
+ label?: string;
11
+ position?: TooltipPosition;
12
+ disabled?: boolean;
13
+ singleLine?: boolean;
14
+ className?: string;
15
+ children: ReactElement;
16
+ ref?: Ref<HTMLElement> | null;
17
+ }
18
+
19
+ export const Tooltip: FC<Props> = ({
20
+ label,
21
+ position = 'top',
22
+ disabled,
23
+ singleLine,
24
+ className,
25
+ children,
26
+ ref,
27
+ }) => {
28
+ const [newPosition, setNewPosition] = useState<TooltipPosition | ''>('');
29
+
30
+ const internalRef = useRef<HTMLElement>(null);
31
+ const tooltipRef = useRef<HTMLDivElement>(null);
32
+
33
+ useEffect(() => {
34
+ if (!disabled && !!label) {
35
+ const getContainer = () => {
36
+ if (ref && 'current' in ref) {
37
+ return ref.current;
38
+ }
39
+ return internalRef.current;
40
+ };
41
+
42
+ const container = getContainer();
43
+ const tooltip = tooltipRef.current;
44
+
45
+ const onMouseEnter = () => {
46
+ if (container && tooltip) {
47
+ setAbsolutePosition(container, tooltip, position, setNewPosition);
48
+ tooltip.classList.add('visible');
49
+ }
50
+ };
51
+ const onMouseLeave = () => tooltip?.classList.remove('visible');
52
+
53
+ if (container) {
54
+ container.addEventListener('mouseenter', onMouseEnter);
55
+ container.addEventListener('mouseleave', onMouseLeave);
56
+
57
+ return () => {
58
+ container.removeEventListener('mouseenter', onMouseEnter);
59
+ container.removeEventListener('mouseleave', onMouseLeave);
60
+ };
61
+ }
62
+ }
63
+ }, [disabled, label, position, ref]);
64
+
65
+ return !!label && !disabled ? (
66
+ <>
67
+ {/* @ts-ignore */}
68
+ {cloneElement(children, { ref: ref || internalRef })}
69
+ {createPortal(
70
+ <div
71
+ ref={tooltipRef}
72
+ className={clsx('tooltip-container', className, {
73
+ 'no-wrap': singleLine,
74
+ })}
75
+ >
76
+ <div className="tooltip">
77
+ <div className={clsx('arrow', newPosition || position)} />
78
+ <div>{label}</div>
79
+ </div>
80
+ </div>,
81
+ rootDir
82
+ )}
83
+ </>
84
+ ) : (
85
+ children
86
+ );
87
+ };
88
+
89
+ const setAbsolutePosition = (
90
+ containerEl: HTMLElement,
91
+ targetEl: HTMLDivElement,
92
+ position: TooltipPosition,
93
+ setNewPosition: Dispatch<SetStateAction<TooltipPosition | ''>>
94
+ ) => {
95
+ const containerRect = containerEl.getBoundingClientRect();
96
+ const tooltipRect = targetEl.getBoundingClientRect();
97
+ const margin = 16; // Distance from container
98
+ const screenPadding = 8; // Minimum distance from screen edges
99
+
100
+ if (position === 'bottom' || position === 'top') {
101
+ const bottom = Math.floor(containerRect.bottom + margin);
102
+ const top = Math.floor(containerRect.top - tooltipRect.height - margin);
103
+ let leftCenter = Math.floor(
104
+ containerRect.left + containerRect.width / 2 - tooltipRect.width / 2
105
+ );
106
+
107
+ // Check if tooltip overflows horizontally and adjust
108
+ if (leftCenter < screenPadding) {
109
+ targetEl.style.width = `${tooltipRect.width + leftCenter}px`;
110
+ leftCenter = screenPadding;
111
+ } else if (leftCenter + tooltipRect.width > window.innerWidth - screenPadding) {
112
+ leftCenter = window.innerWidth - tooltipRect.width - screenPadding;
113
+ }
114
+
115
+ const reverse =
116
+ position === 'top' ? top < 0 : bottom + tooltipRect.height > window.innerHeight;
117
+
118
+ setNewPosition(reverse ? (position === 'bottom' ? 'top' : 'bottom') : '');
119
+
120
+ let finalTop =
121
+ position === 'bottom' ? (reverse ? top : bottom) : reverse ? bottom : top;
122
+
123
+ // Ensure tooltip doesn't go above screen
124
+ if (finalTop < screenPadding) {
125
+ finalTop = screenPadding;
126
+ }
127
+ // Ensure tooltip doesn't go below screen
128
+ if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
129
+ finalTop = window.innerHeight - tooltipRect.height - screenPadding;
130
+ }
131
+
132
+ targetEl.style.top = `${finalTop}px`;
133
+ targetEl.style.left = `${leftCenter}px`;
134
+ } else if (position === 'right') {
135
+ let finalTop = Math.floor(
136
+ containerRect.top + containerRect.height / 2 - tooltipRect.height / 2
137
+ );
138
+ let finalLeft = Math.floor(containerRect.right + margin);
139
+
140
+ // Check if tooltip overflows vertically and adjust
141
+ if (finalTop < screenPadding) {
142
+ finalTop = screenPadding;
143
+ } else if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
144
+ finalTop = window.innerHeight - tooltipRect.height - screenPadding;
145
+ }
146
+
147
+ // Check if tooltip overflows to the right and flip to left
148
+ if (finalLeft + tooltipRect.width > window.innerWidth - screenPadding) {
149
+ finalLeft = Math.floor(containerRect.left - tooltipRect.width - margin);
150
+ setNewPosition('left');
151
+
152
+ // If it still overflows on the left, position it at the edge
153
+ if (finalLeft < screenPadding) {
154
+ finalLeft = screenPadding;
155
+ }
156
+ } else {
157
+ setNewPosition('');
158
+ }
159
+
160
+ targetEl.style.top = `${finalTop}px`;
161
+ targetEl.style.left = `${finalLeft}px`;
162
+ } else if (position === 'left') {
163
+ let finalTop = Math.floor(
164
+ containerRect.top + containerRect.height / 2 - tooltipRect.height / 2
165
+ );
166
+ let finalLeft = Math.floor(containerRect.left - tooltipRect.width - margin);
167
+
168
+ // Check if tooltip overflows vertically and adjust
169
+ if (finalTop < screenPadding) {
170
+ finalTop = screenPadding;
171
+ } else if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
172
+ finalTop = window.innerHeight - tooltipRect.height - screenPadding;
173
+ }
174
+
175
+ // Check if tooltip overflows to the left and flip to right
176
+ if (finalLeft < screenPadding) {
177
+ finalLeft = Math.floor(containerRect.right + margin);
178
+ setNewPosition('right');
179
+
180
+ // If it still overflows on the right, position it at the edge
181
+ if (finalLeft + tooltipRect.width > window.innerWidth - screenPadding) {
182
+ finalLeft = window.innerWidth - tooltipRect.width - screenPadding;
183
+ }
184
+ } else {
185
+ setNewPosition('');
186
+ }
187
+
188
+ targetEl.style.top = `${finalTop}px`;
189
+ targetEl.style.left = `${finalLeft}px`;
190
+ }
191
+ };
@@ -1,22 +1,22 @@
1
- import type { FC } from 'react';
2
- import type { ITreeItem } from '../../types/ITree';
3
- import { TreeItem } from './TreeItem';
4
-
5
- interface Props {
6
- data: ITreeItem[];
7
- selectedItemUuid?: string;
8
- onClick: (itemUuid: string) => void;
9
- }
10
-
11
- export const Tree: FC<Props> = ({ data, selectedItemUuid, onClick }) => (
12
- <div>
13
- {data.map(item => (
14
- <TreeItem
15
- key={item.uuid}
16
- item={item}
17
- onClick={onClick}
18
- selectedItemUuid={selectedItemUuid}
19
- />
20
- ))}
21
- </div>
22
- );
1
+ import type { FC } from 'react';
2
+ import type { ITreeItem } from '../../types/ITree';
3
+ import { TreeItem } from './TreeItem';
4
+
5
+ interface Props {
6
+ data: ITreeItem[];
7
+ selectedItemUuid?: string;
8
+ onClick: (itemUuid: string) => void;
9
+ }
10
+
11
+ export const Tree: FC<Props> = ({ data, selectedItemUuid, onClick }) => (
12
+ <div>
13
+ {data.map(item => (
14
+ <TreeItem
15
+ key={item.uuid}
16
+ item={item}
17
+ onClick={onClick}
18
+ selectedItemUuid={selectedItemUuid}
19
+ />
20
+ ))}
21
+ </div>
22
+ );
@@ -1,57 +1,57 @@
1
- import type { FC } from 'react';
2
- import type { ITreeItem } from '../../types/ITree';
3
- import { useState } from 'react';
4
- import clsx from 'clsx';
5
- import { faChevronRight } from '../../assets/icons';
6
- import { IconButton } from '../Button/IconButton';
7
- import { Collapse } from '../Helper/Collapse';
8
-
9
- interface Props {
10
- item: ITreeItem;
11
- onClick: (itemUuid: string) => void;
12
- selectedItemUuid?: string;
13
- className?: string;
14
- }
15
-
16
- export const TreeItem: FC<Props> = ({ item, onClick, selectedItemUuid, className }) => {
17
- const [isOpen, setIsOpen] = useState(false);
18
-
19
- const hasChildren = !!item.children?.length;
20
- return (
21
- <div className={clsx('tree-item', className)}>
22
- <div className="flex align-center">
23
- <div className="extendable-icon">
24
- {hasChildren && (
25
- <IconButton
26
- icon={faChevronRight}
27
- onClick={() => setIsOpen(!isOpen)}
28
- size="s"
29
- className={clsx('rotate', { rotate90: isOpen })}
30
- />
31
- )}
32
- </div>
33
- <div
34
- className={clsx('tree-item-name clickable', {
35
- active: selectedItemUuid === item.uuid,
36
- })}
37
- onClick={() => onClick(item.uuid)}
38
- >
39
- {item.name}
40
- </div>
41
- </div>
42
- {hasChildren && (
43
- <Collapse isOpen={isOpen}>
44
- {item.children?.map((child: ITreeItem) => (
45
- <TreeItem
46
- key={child.uuid}
47
- item={child}
48
- onClick={onClick}
49
- className={clsx('ml-3', className)}
50
- selectedItemUuid={selectedItemUuid}
51
- />
52
- ))}
53
- </Collapse>
54
- )}
55
- </div>
56
- );
57
- };
1
+ import type { FC } from 'react';
2
+ import type { ITreeItem } from '../../types/ITree';
3
+ import { useState } from 'react';
4
+ import clsx from 'clsx';
5
+ import { faChevronRight } from '../../assets/icons';
6
+ import { IconButton } from '../Button/IconButton';
7
+ import { Collapse } from '../Helper/Collapse';
8
+
9
+ interface Props {
10
+ item: ITreeItem;
11
+ onClick: (itemUuid: string) => void;
12
+ selectedItemUuid?: string;
13
+ className?: string;
14
+ }
15
+
16
+ export const TreeItem: FC<Props> = ({ item, onClick, selectedItemUuid, className }) => {
17
+ const [isOpen, setIsOpen] = useState(false);
18
+
19
+ const hasChildren = !!item.children?.length;
20
+ return (
21
+ <div className={clsx('tree-item', className)}>
22
+ <div className="flex align-center">
23
+ <div className="extendable-icon">
24
+ {hasChildren && (
25
+ <IconButton
26
+ icon={faChevronRight}
27
+ onClick={() => setIsOpen(!isOpen)}
28
+ size="s"
29
+ className={clsx('rotate', { rotate90: isOpen })}
30
+ />
31
+ )}
32
+ </div>
33
+ <div
34
+ className={clsx('tree-item-name clickable', {
35
+ active: selectedItemUuid === item.uuid,
36
+ })}
37
+ onClick={() => onClick(item.uuid)}
38
+ >
39
+ {item.name}
40
+ </div>
41
+ </div>
42
+ {hasChildren && (
43
+ <Collapse isOpen={isOpen}>
44
+ {item.children?.map((child: ITreeItem) => (
45
+ <TreeItem
46
+ key={child.uuid}
47
+ item={child}
48
+ onClick={onClick}
49
+ className={clsx('ml-3', className)}
50
+ selectedItemUuid={selectedItemUuid}
51
+ />
52
+ ))}
53
+ </Collapse>
54
+ )}
55
+ </div>
56
+ );
57
+ };
@@ -1,17 +1,17 @@
1
- import type { ComponentProps, FC, ReactNode } from 'react';
2
- import { Header } from '../Header/Header';
3
- import { Sidebar } from '../Sidebar/Sidebar';
4
-
5
- interface Props {
6
- header: ComponentProps<typeof Header>;
7
- sidebar: ComponentProps<typeof Sidebar>;
8
- children: ReactNode;
9
- }
10
-
11
- export const AppLayout: FC<Props> = ({ header, sidebar, children }) => (
12
- <div className="app-layout">
13
- <Header {...header} />
14
- <Sidebar {...sidebar} />
15
- <div className="app-content">{children}</div>
16
- </div>
17
- );
1
+ import type { ComponentProps, FC, ReactNode } from 'react';
2
+ import { Header } from '../Header/Header';
3
+ import { Sidebar } from '../Sidebar/Sidebar';
4
+
5
+ interface Props {
6
+ header: ComponentProps<typeof Header>;
7
+ sidebar: ComponentProps<typeof Sidebar>;
8
+ children: ReactNode;
9
+ }
10
+
11
+ export const AppLayout: FC<Props> = ({ header, sidebar, children }) => (
12
+ <div className="app-layout">
13
+ <Header {...header} />
14
+ <Sidebar {...sidebar} />
15
+ <div className="app-content">{children}</div>
16
+ </div>
17
+ );
@@ -1,10 +1,10 @@
1
- import type { FC, ReactNode } from 'react';
2
-
3
- interface Props {
4
- condition: boolean;
5
- wrapper: (children: ReactNode) => ReactNode;
6
- children: ReactNode;
7
- }
8
-
9
- export const ConditionalWrapper: FC<Props> = ({ condition, wrapper, children }) =>
10
- condition ? wrapper(children) : children;
1
+ import type { FC, ReactNode } from 'react';
2
+
3
+ interface Props {
4
+ condition: boolean;
5
+ wrapper: (children: ReactNode) => ReactNode;
6
+ children: ReactNode;
7
+ }
8
+
9
+ export const ConditionalWrapper: FC<Props> = ({ condition, wrapper, children }) =>
10
+ condition ? wrapper(children) : children;