@inceptionbg/iui 2.0.8 → 2.0.10

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 (138) hide show
  1. package/dist/icons/index.d.ts +2 -2
  2. package/dist/icons/index.js +1 -1
  3. package/dist/index.d.ts +286 -259
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/iui.css +1 -1
  7. package/idea/GridTable/GridTable.tsx +119 -0
  8. package/idea/GridTable/gridTable.scss +42 -0
  9. package/{src/components → idea}/Table/Components/Print/CustomTablePrint.tsx +2 -2
  10. package/{src/components → idea}/Table/Components/Print/TablePrint.tsx +2 -2
  11. package/{src/components → idea}/Table/Components/SetTableFilter.tsx +1 -1
  12. package/{src/components → idea}/Table/Components/TableOptions.tsx +4 -4
  13. package/idea/{Table2 → Table}/Table.tsx +151 -281
  14. package/idea/Table/hooks/useDefaultTemplate.ts +20 -0
  15. package/{src/components → idea}/Table/hooks/useTableKeyboard.ts +1 -2
  16. package/idea/Table/hooks/useTableSelect.ts +11 -0
  17. package/package.json +1 -1
  18. package/src/assets/icons/index.ts +1 -1
  19. package/src/assets/icons/light/faClipboardCheck.ts +15 -0
  20. package/src/assets/icons/light/faHouse.ts +15 -15
  21. package/src/assets/icons/light/faIdBadge.ts +15 -15
  22. package/src/assets/icons/light/faPen.ts +15 -0
  23. package/src/components/Button/IconButton.tsx +3 -1
  24. package/src/components/Dialog/Dialog.tsx +59 -123
  25. package/src/components/Dialog/components/DialogFooter.tsx +92 -0
  26. package/src/components/Dialog/hooks/useDialogKeyboard.ts +6 -5
  27. package/src/components/Header/Header.tsx +1 -1
  28. package/src/components/Inputs/DateInput/DateInput.tsx +108 -102
  29. package/src/components/Inputs/DateInput/components/DatePartInput.tsx +7 -3
  30. package/src/components/Inputs/InputWrapper.tsx +6 -1
  31. package/src/components/Inputs/SearchInput.tsx +9 -4
  32. package/src/components/Inputs/Select2/Select.tsx +65 -30
  33. package/src/components/Inputs/Select2/select.scss +13 -14
  34. package/src/components/Inputs/Selects/components/SelectWrapper.tsx +4 -2
  35. package/src/components/Inputs/Selects/utils/selectStyles.ts +9 -12
  36. package/src/components/Menu/Menu.tsx +10 -2
  37. package/src/components/Menu/MenuItem.tsx +11 -10
  38. package/src/components/Menu/hooks/useMenuPosition.tsx +23 -6
  39. package/src/components/Pullover/Pullover.tsx +122 -59
  40. package/src/components/Table/Table.tsx +78 -342
  41. package/src/components/Table/components/edit/TableEditRow.tsx +69 -0
  42. package/src/components/Table/components/filters/FilterItem.tsx +15 -0
  43. package/src/components/Table/components/filters/TableFilters.tsx +125 -0
  44. package/src/components/Table/components/footer/TableFooter.tsx +128 -0
  45. package/src/components/Table/components/header/TableHeader.tsx +42 -0
  46. package/src/components/Table/components/header/TableHeaderRow.tsx +47 -0
  47. package/src/components/Table/components/items/TableItemActions.tsx +66 -0
  48. package/src/components/Table/components/select/TableSelect.tsx +49 -0
  49. package/src/components/Table/components/sort/TableSort.tsx +52 -0
  50. package/src/components/Table/contexts/TableContext.tsx +123 -0
  51. package/src/components/Table/hooks/localHooks/useLocalTableColumns.tsx +73 -0
  52. package/src/components/Table/hooks/localHooks/useLocalTableData.tsx +78 -0
  53. package/src/components/Table/hooks/localHooks/useLocalTableKeyboard.ts +173 -0
  54. package/src/components/Table/hooks/localHooks/useLocalTablePagination.ts +12 -0
  55. package/src/components/Table/hooks/useTableEdit.tsx +111 -0
  56. package/src/components/Table/hooks/useTableFilterFields.tsx +150 -0
  57. package/src/components/Table/hooks/useTablePagination.ts +16 -0
  58. package/src/components/Table/hooks/useTableSearch.ts +29 -0
  59. package/src/components/Table/hooks/useTableSort.ts +8 -0
  60. package/src/components/Tooltip/Tooltip.tsx +1 -1
  61. package/src/components/Wrappers/PageLayout.tsx +9 -12
  62. package/src/hooks/useGetFocusableElements.ts +42 -0
  63. package/src/hooks/useLocalPopoverControl.ts +38 -0
  64. package/src/hooks/usePopupControl.ts +13 -0
  65. package/src/index.ts +53 -39
  66. package/src/styles/components/_accordions.scss +1 -1
  67. package/src/styles/components/_badge.scss +4 -3
  68. package/src/styles/components/_card.scss +1 -1
  69. package/src/styles/components/_dialog.scss +8 -8
  70. package/src/styles/components/_input.scss +1 -1
  71. package/src/styles/components/_inputCheckbox.scss +1 -1
  72. package/src/styles/components/_inputDateTime.scss +2 -2
  73. package/src/styles/components/_inputRadio.scss +1 -1
  74. package/src/styles/components/_inputSelect.scss +6 -4
  75. package/src/styles/components/_menu-v2.scss +1 -1
  76. package/src/styles/components/_menu.scss +23 -15
  77. package/src/styles/components/_pullover.scss +74 -18
  78. package/src/styles/components/_table.scss +151 -142
  79. package/src/styles/components/_widget.scss +1 -1
  80. package/src/styles/variables/_bp.scss +1 -0
  81. package/src/styles/variables/_variables.scss +4 -2
  82. package/src/types/IKeyboard.ts +2 -1
  83. package/src/types/IMenu.ts +1 -0
  84. package/src/types/ISelect.ts +1 -0
  85. package/src/types/ITable.ts +87 -80
  86. package/src/utils/fileUtils.ts +3 -3
  87. package/src/utils/i18n/i18nIUICyrilic.ts +4 -0
  88. package/src/utils/i18n/i18nIUILatin.ts +3 -1
  89. package/src/utils/i18n/i18nIUIMe.ts +4 -0
  90. package/src/utils/{ObjectUtils.ts → objectUtils.ts} +8 -8
  91. package/src/utils/popupUtils.ts +82 -0
  92. package/src/utils/{TableUtils.ts → tableUtils.ts} +5 -5
  93. package/src/utils/{Toasts.ts → toasts.ts} +6 -6
  94. package/src/utils/{UrlUtils.ts → urlUtils.ts} +4 -4
  95. package/idea/Table2/Components/Columns/ColumnsList.tsx +0 -56
  96. package/idea/Table2/Components/Columns/SetColumnsList.tsx +0 -107
  97. package/idea/Table2/Components/Edit/ItemActionsMenu.tsx +0 -87
  98. package/idea/Table2/Components/Edit/ItemEditOptionsButtons.tsx +0 -32
  99. package/idea/Table2/Components/Edit/TableEditRow.tsx +0 -56
  100. package/idea/Table2/Components/FilterItem.tsx +0 -20
  101. package/idea/Table2/Components/Header/TableHeader.tsx +0 -35
  102. package/idea/Table2/Components/Header/TableHeaderRow.tsx +0 -37
  103. package/idea/Table2/Components/Print/CustomTablePrint.tsx +0 -119
  104. package/idea/Table2/Components/Print/TablePrint.tsx +0 -208
  105. package/idea/Table2/Components/SetSortList.tsx +0 -33
  106. package/idea/Table2/Components/SetTableFilter.tsx +0 -90
  107. package/idea/Table2/Components/TableFooter.tsx +0 -107
  108. package/idea/Table2/Components/TableOptions.tsx +0 -211
  109. package/idea/Table2/Components/Templates/TemplateCreate.tsx +0 -75
  110. package/idea/Table2/Components/Templates/TemplateCreateDefault.tsx +0 -45
  111. package/idea/Table2/Components/Templates/TemplateList.tsx +0 -167
  112. package/idea/Table2/Components/Templates/repo/TemplateRepo.ts +0 -51
  113. package/idea/Table2/_table.scss +0 -300
  114. package/idea/Table2/hooks/useDefaultTemplate.ts +0 -22
  115. package/idea/Table2/hooks/useTableKeyboard.ts +0 -115
  116. package/src/assets/icons/light/faPenField.ts +0 -15
  117. package/src/assets/icons/solid/faMagnifyingGlass.ts +0 -15
  118. package/src/components/Dialog/DeleteItemDialog.tsx +0 -52
  119. package/src/components/Dialog/hooks/useDialogObserver.ts +0 -21
  120. /package/{src/components → idea}/Table/Components/Columns/ColumnsList.tsx +0 -0
  121. /package/{src/components → idea}/Table/Components/Columns/SetColumnsList.tsx +0 -0
  122. /package/{src/components → idea}/Table/Components/Edit/ItemActionsMenu.tsx +0 -0
  123. /package/{src/components → idea}/Table/Components/Edit/ItemEditOptionsButtons.tsx +0 -0
  124. /package/{src/components → idea}/Table/Components/Edit/TableEditRow.tsx +0 -0
  125. /package/{src/components → idea}/Table/Components/FilterItem.tsx +0 -0
  126. /package/{src/components → idea}/Table/Components/Header/TableHeader.tsx +0 -0
  127. /package/{src/components → idea}/Table/Components/Header/TableHeaderRow.tsx +0 -0
  128. /package/{src/components → idea}/Table/Components/SetSortList.tsx +0 -0
  129. /package/{src/components → idea}/Table/Components/TableFooter.tsx +0 -0
  130. /package/{src/components → idea}/Table/Components/Templates/TemplateCreate.tsx +0 -0
  131. /package/{src/components → idea}/Table/Components/Templates/TemplateCreateDefault.tsx +0 -0
  132. /package/{src/components → idea}/Table/Components/Templates/TemplateList.tsx +0 -0
  133. /package/{src/components → idea}/Table/Components/Templates/repo/TemplateRepo.ts +0 -0
  134. /package/src/utils/{DateUtils.ts → dateUtils.ts} +0 -0
  135. /package/src/utils/{LocalStorageHelper.ts → localStorageHelper.ts} +0 -0
  136. /package/src/utils/{NumberUtils.ts → numberUtils.ts} +0 -0
  137. /package/src/utils/{RootDir.ts → rootDir.ts} +0 -0
  138. /package/src/utils/{StringUtils.ts → stringUtils.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inceptionbg/iui",
3
- "version": "2.0.8",
3
+ "version": "2.0.10",
4
4
  "description": "UI components, elements & utils for Inception ecosystem",
5
5
  "type": "module",
6
6
  "exports": {
@@ -11,7 +11,7 @@ export * from './light/faHouse';
11
11
  export * from './light/faIdBadge';
12
12
  export * from './light/faLink';
13
13
  export * from './light/faMagnifyingGlass';
14
- export * from './light/faPenField';
14
+ export * from './light/faPen';
15
15
  export * from './light/faPrint';
16
16
  export * from './light/faQuestion';
17
17
  export * from './light/faRotateRight';
@@ -0,0 +1,15 @@
1
+ import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
+
3
+ const prefix = "fal";
4
+ const iconName = "clipboard-check";
5
+ const width = 384;
6
+ const height = 512;
7
+ const unicode = "f46c";
8
+ const svgPathData =
9
+ "M320 64c-8.844 0-16 7.156-16 16S311.2 96 320 96c17.64 0 32 14.34 32 32v320c0 17.66-14.36 32-32 32H64c-17.64 0-32-14.34-32-32V128c0-17.66 14.36-32 32-32c8.844 0 16-7.156 16-16S72.84 64 64 64C28.7 64 0 92.72 0 128v320c0 35.28 28.7 64 64 64h256c35.3 0 64-28.72 64-64V128C384 92.72 355.3 64 320 64zM112 128h160C280.8 128 288 120.8 288 112S280.8 96 272 96h-24.88C252.6 86.55 256 75.72 256 64c0-35.35-28.65-64-64-64S128 28.65 128 64c0 11.72 3.379 22.55 8.877 32H112C103.2 96 96 103.2 96 112S103.2 128 112 128zM192 32c17.64 0 32 14.36 32 32s-14.36 32-32 32S160 81.64 160 64S174.4 32 192 32zM84.69 299.3l64 64C151.8 366.4 155.9 368 160 368s8.188-1.562 11.31-4.688l128-128c6.25-6.25 6.25-16.38 0-22.62s-16.38-6.25-22.62 0L160 329.4L107.3 276.7c-6.25-6.25-16.38-6.25-22.62 0S78.44 293.1 84.69 299.3z";
10
+
11
+ export const faClipboardCheck: IconDefinition = {
12
+ prefix,
13
+ iconName,
14
+ icon: [width, height, [], unicode, svgPathData],
15
+ };
@@ -1,15 +1,15 @@
1
- import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
-
3
- const prefix = "fal";
4
- const iconName = "house";
5
- const width = 576;
6
- const height = 512;
7
- const unicode = "f015";
8
- const svgPathData =
9
- "M570.6 244C577.2 249.8 577.8 259.1 571.1 266.6C566.2 273.2 556 273.8 549.4 267.1L512 234.1V432C512 476.2 476.2 512 432 512H144C99.82 512 64 476.2 64 432V234.1L26.59 267.1C19.96 273.8 9.849 273.2 4.003 266.6C-1.844 259.1-1.212 249.8 5.414 244L277.4 4.002C283.5-1.334 292.5-1.334 298.6 4.002L570.6 244zM144 480H208V320C208 302.3 222.3 288 240 288H336C353.7 288 368 302.3 368 320V480H432C458.5 480 480 458.5 480 432V206.7L288 37.34L96 206.7V432C96 458.5 117.5 480 144 480zM240 480H336V320H240V480z";
10
-
11
- export const faHouse: IconDefinition = {
12
- prefix,
13
- iconName,
14
- icon: [width, height, [], unicode, svgPathData],
15
- };
1
+ import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
+
3
+ const prefix = "fal";
4
+ const iconName = "house";
5
+ const width = 576;
6
+ const height = 512;
7
+ const unicode = "f015";
8
+ const svgPathData =
9
+ "M570.6 244C577.2 249.8 577.8 259.1 571.1 266.6C566.2 273.2 556 273.8 549.4 267.1L512 234.1V432C512 476.2 476.2 512 432 512H144C99.82 512 64 476.2 64 432V234.1L26.59 267.1C19.96 273.8 9.849 273.2 4.003 266.6C-1.844 259.1-1.212 249.8 5.414 244L277.4 4.002C283.5-1.334 292.5-1.334 298.6 4.002L570.6 244zM144 480H208V320C208 302.3 222.3 288 240 288H336C353.7 288 368 302.3 368 320V480H432C458.5 480 480 458.5 480 432V206.7L288 37.34L96 206.7V432C96 458.5 117.5 480 144 480zM240 480H336V320H240V480z";
10
+
11
+ export const faHouse: IconDefinition = {
12
+ prefix,
13
+ iconName,
14
+ icon: [width, height, [], unicode, svgPathData],
15
+ };
@@ -1,15 +1,15 @@
1
- import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
-
3
- const prefix = "fal";
4
- const iconName = "id-badge";
5
- const width = 384;
6
- const height = 512;
7
- const unicode = "f2c1";
8
- const svgPathData =
9
- "M320 0H64C28.65 0 0 28.65 0 64v384c0 35.35 28.65 64 64 64h256c35.35 0 64-28.65 64-64V64C384 28.65 355.3 0 320 0zM352 448c0 17.64-14.36 32-32 32H64c-17.64 0-32-14.36-32-32V64c0-17.64 14.36-32 32-32h256c17.64 0 32 14.36 32 32V448zM192 288c35.35 0 64-28.65 64-64s-28.65-64-64-64S128 188.7 128 224S156.7 288 192 288zM192 192c17.64 0 32 14.36 32 32s-14.36 32-32 32S160 241.6 160 224S174.4 192 192 192zM224 320H160c-44.18 0-80 35.82-80 80C80 408.8 87.16 416 96 416c8.838 0 16-7.164 16-16C112 373.5 133.5 352 160 352h64c26.51 0 48 21.49 48 48c0 8.836 7.164 16 16 16c8.838 0 16-7.164 16-16C304 355.8 268.2 320 224 320zM144 96h96C248.8 96 256 88.84 256 80S248.8 64 240 64h-96C135.2 64 128 71.16 128 80S135.2 96 144 96z";
10
-
11
- export const faIdBadge: IconDefinition = {
12
- prefix,
13
- iconName,
14
- icon: [width, height, [], unicode, svgPathData],
15
- };
1
+ import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
+
3
+ const prefix = "fal";
4
+ const iconName = "id-badge";
5
+ const width = 384;
6
+ const height = 512;
7
+ const unicode = "f2c1";
8
+ const svgPathData =
9
+ "M320 0H64C28.65 0 0 28.65 0 64v384c0 35.35 28.65 64 64 64h256c35.35 0 64-28.65 64-64V64C384 28.65 355.3 0 320 0zM352 448c0 17.64-14.36 32-32 32H64c-17.64 0-32-14.36-32-32V64c0-17.64 14.36-32 32-32h256c17.64 0 32 14.36 32 32V448zM192 288c35.35 0 64-28.65 64-64s-28.65-64-64-64S128 188.7 128 224S156.7 288 192 288zM192 192c17.64 0 32 14.36 32 32s-14.36 32-32 32S160 241.6 160 224S174.4 192 192 192zM224 320H160c-44.18 0-80 35.82-80 80C80 408.8 87.16 416 96 416c8.838 0 16-7.164 16-16C112 373.5 133.5 352 160 352h64c26.51 0 48 21.49 48 48c0 8.836 7.164 16 16 16c8.838 0 16-7.164 16-16C304 355.8 268.2 320 224 320zM144 96h96C248.8 96 256 88.84 256 80S248.8 64 240 64h-96C135.2 64 128 71.16 128 80S135.2 96 144 96z";
10
+
11
+ export const faIdBadge: IconDefinition = {
12
+ prefix,
13
+ iconName,
14
+ icon: [width, height, [], unicode, svgPathData],
15
+ };
@@ -0,0 +1,15 @@
1
+ import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
+
3
+ const prefix = "fal";
4
+ const iconName = "pen";
5
+ const width = 512;
6
+ const height = 512;
7
+ const unicode = "f304";
8
+ const svgPathData =
9
+ "M493.2 56.26l-37.51-37.51C443.2 6.252 426.8 0 410.5 0c-16.38 0-32.76 6.25-45.26 18.75L45.11 338.9c-8.568 8.566-14.53 19.39-17.18 31.21l-27.61 122.8C-1.7 502.1 6.158 512 15.95 512c1.047 0 2.116-.1034 3.198-.3202c0 0 84.61-17.95 122.8-26.93c11.54-2.717 21.87-8.523 30.25-16.9l321.2-321.2C518.3 121.7 518.2 81.26 493.2 56.26zM149.5 445.2c-4.219 4.219-9.252 7.039-14.96 8.383c-24.68 5.811-69.64 15.55-97.46 21.52l22.04-98.01c1.332-5.918 4.303-11.31 8.594-15.6l247.6-247.6l82.76 82.76L149.5 445.2zM470.7 124l-50.03 50.02l-82.76-82.76l49.93-49.93C393.9 35.33 401.9 32 410.5 32s16.58 3.33 22.63 9.375l37.51 37.51C483.1 91.37 483.1 111.6 470.7 124z";
10
+
11
+ export const faPen: IconDefinition = {
12
+ prefix,
13
+ iconName,
14
+ icon: [width, height, [], unicode, svgPathData],
15
+ };
@@ -14,6 +14,7 @@ export interface IIconButtonProps {
14
14
  disabled?: boolean;
15
15
  active?: boolean;
16
16
  tooltip?: string;
17
+ type?: ButtonHTMLAttributes<HTMLButtonElement>['type'];
17
18
  className?: string;
18
19
  buttonProps?: ButtonHTMLAttributes<HTMLButtonElement>;
19
20
  ref?: Ref<HTMLButtonElement>;
@@ -28,6 +29,7 @@ export const IconButton: FC<IIconButtonProps> = ({
28
29
  disabled,
29
30
  active,
30
31
  tooltip,
32
+ type = 'button',
31
33
  className,
32
34
  buttonProps,
33
35
  ref,
@@ -40,7 +42,7 @@ export const IconButton: FC<IIconButtonProps> = ({
40
42
  active,
41
43
  })}
42
44
  onClick={onClick}
43
- type={buttonProps?.type || onClick ? 'button' : 'submit'}
45
+ type={type}
44
46
  {...buttonProps}
45
47
  >
46
48
  <FontAwesomeIcon icon={icon} />
@@ -1,52 +1,33 @@
1
- import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2
1
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
2
  import clsx from 'clsx';
4
- import { FC, ReactNode, useCallback, useRef } from 'react';
3
+ import { FC, KeyboardEventHandler, ReactNode, Ref, useRef } from 'react';
5
4
  import { createPortal } from 'react-dom';
6
- import { useTranslation } from 'react-i18next';
7
- import { rootDir } from '../../utils/RootDir';
8
- import { Button, IButtonColor, IButtonVariant } from '../Button/Button';
5
+ import { rootDir } from '../../utils/rootDir';
9
6
  import { Loader } from '../Loader/Loader';
10
7
  import { ConditionalWrapper } from '../Wrappers/ConditionalWrapper';
11
- import { useDialogKeyboard } from './hooks/useDialogKeyboard';
12
8
  import { faXmark } from '../../assets/icons';
13
9
  import { IconButton } from '../Button/IconButton';
14
10
  import { infoIcons } from '../../utils/icons';
15
11
  import { IInfoType } from '../../types/IInfo';
16
12
  import { useBackgroundClose } from '../../hooks/useBackgroundClose';
13
+ import { DialogFooter, IDialogFooterActions } from './components/DialogFooter';
14
+ import {
15
+ PopupControlRef,
16
+ useLocalPopoverControl,
17
+ } from '../../hooks/useLocalPopoverControl';
18
+ import { useGetFocusableElements } from '../../hooks/useGetFocusableElements';
19
+ import { onPopupKeyDown } from '../../utils/popupUtils';
17
20
 
18
21
  interface Props {
22
+ controlRef: Ref<PopupControlRef>;
19
23
  title?: string;
20
24
  titleEl?: ReactNode;
21
25
  desc?: string;
22
26
  descEl?: ReactNode;
23
- isOpen: boolean;
24
- onClose: () => void;
27
+ onFormSubmit?: () => void;
28
+ onCloseCallback?: () => void;
25
29
  isLoading?: boolean;
26
- confirmButton?: {
27
- label?: string;
28
- icon?: IconDefinition;
29
- onClick?: () => void;
30
- onFormSubmit?: () => void;
31
- disabled?: boolean;
32
- keepOpen?: boolean;
33
- isKeyboardDisabled?: boolean;
34
- };
35
- cancelButton?: {
36
- label?: string;
37
- icon?: IconDefinition;
38
- onClick?: () => void;
39
- };
40
- additionalButton?: {
41
- label: string;
42
- icon?: IconDefinition;
43
- onClick?: () => void;
44
- disabled?: boolean;
45
- keepOpen?: boolean;
46
- color?: IButtonColor;
47
- variant?: IButtonVariant;
48
- };
49
- hideActionButtons?: boolean;
30
+ footer?: IDialogFooterActions;
50
31
  isKeyboardDisabled?: boolean;
51
32
  noBackgroundClick?: boolean;
52
33
  noOverflow?: boolean;
@@ -57,18 +38,16 @@ interface Props {
57
38
  }
58
39
 
59
40
  export const Dialog: FC<Props> = ({
41
+ controlRef,
60
42
  title,
61
43
  titleEl,
62
44
  desc,
63
45
  descEl,
64
- isOpen,
65
- onClose,
46
+ onFormSubmit,
47
+ onCloseCallback,
66
48
  isLoading,
67
- confirmButton,
68
- cancelButton,
69
- additionalButton,
49
+ footer,
70
50
  isKeyboardDisabled,
71
- hideActionButtons,
72
51
  noBackgroundClick,
73
52
  noOverflow,
74
53
  type,
@@ -76,58 +55,60 @@ export const Dialog: FC<Props> = ({
76
55
  className,
77
56
  children,
78
57
  }) => {
79
- const { t } = useTranslation();
80
-
81
- const portalRef = useRef<HTMLDivElement>(null);
82
58
  const formRef = useRef<HTMLFormElement>(null);
83
59
 
84
- const handleClose = useCallback(() => {
85
- portalRef.current?.classList.add('closing');
86
- setTimeout(onClose, 200);
87
- }, [portalRef, onClose]);
60
+ const { elementRef, isOpen, onClose } = useLocalPopoverControl({
61
+ controlRef,
62
+ onCloseCallback,
63
+ });
88
64
 
89
- useDialogKeyboard({
65
+ const focusableElements = useGetFocusableElements({
66
+ elementRef,
90
67
  isOpen,
91
- isDisabled: isKeyboardDisabled,
92
- onClose: handleClose,
93
- submit: {
94
- onEnter: () => {
95
- if (confirmButton) {
96
- if (confirmButton.onFormSubmit) {
97
- formRef.current?.requestSubmit();
98
- } else {
99
- confirmButton.onClick?.();
100
- !confirmButton.keepOpen && handleClose();
101
- }
102
- } else {
103
- cancelButton?.onClick ? cancelButton.onClick() : handleClose();
104
- }
105
- },
106
- isDisabled: !confirmButton?.disabled && !confirmButton?.isKeyboardDisabled,
107
- },
108
68
  });
109
69
 
110
70
  useBackgroundClose({
111
- portalRef,
71
+ portalRef: elementRef,
112
72
  disabled: noBackgroundClick || !isOpen,
113
- handleClose,
73
+ handleClose: onClose,
114
74
  });
115
75
 
76
+ const onKeyDown: KeyboardEventHandler<HTMLDivElement> = event => {
77
+ !isKeyboardDisabled &&
78
+ onPopupKeyDown(event, {
79
+ onClose,
80
+ enter: {
81
+ onAction: () => {
82
+ footer?.confirmButton.onClick?.();
83
+ !footer?.confirmButton.keepOpen && onClose();
84
+ },
85
+ disabled: !footer?.confirmButton.onClick,
86
+ },
87
+ focusableElements,
88
+ });
89
+ };
90
+
116
91
  return isOpen
117
92
  ? createPortal(
118
- <div ref={portalRef} className="iui-dialog">
93
+ <div
94
+ ref={elementRef}
95
+ className="iui-dialog"
96
+ aria-label="popup"
97
+ onKeyDown={onKeyDown}
98
+ tabIndex={-1}
99
+ >
119
100
  <Loader isLoading={!!isLoading}>
120
101
  <div className={clsx('iui-dialog-container', size, type, className)}>
121
102
  <ConditionalWrapper
122
- condition={!!confirmButton?.onFormSubmit}
103
+ condition={!!onFormSubmit}
123
104
  wrapper={children => (
124
105
  <form
125
106
  ref={formRef}
126
107
  onSubmit={e => {
127
108
  e.preventDefault();
128
109
  e.stopPropagation();
129
- confirmButton?.onFormSubmit?.();
130
- !confirmButton?.keepOpen && handleClose();
110
+ onFormSubmit?.();
111
+ !footer?.confirmButton?.keepOpen && onClose();
131
112
  }}
132
113
  >
133
114
  {children}
@@ -151,10 +132,11 @@ export const Dialog: FC<Props> = ({
151
132
  {title ? <h4>{title}</h4> : titleEl}
152
133
  <IconButton
153
134
  icon={faXmark}
154
- onClick={handleClose}
135
+ onClick={onClose}
155
136
  color="neutral"
156
137
  size="l"
157
138
  className="close-icon"
139
+ buttonProps={{ tabIndex: -1 }}
158
140
  />
159
141
  </div>
160
142
  {desc ? <p className="iui-dialog-desc">{desc}</p> : descEl}
@@ -162,59 +144,13 @@ export const Dialog: FC<Props> = ({
162
144
  </div>
163
145
  {children}
164
146
  </div>
165
- {!hideActionButtons && (
166
- <div className="iui-dialog-actions">
167
- <Button
168
- label={
169
- cancelButton?.label || (confirmButton ? t('Cancel') : t('Close'))
170
- }
171
- icon={cancelButton?.icon}
172
- variant={confirmButton ? 'outlined' : 'solid'}
173
- onClick={e => {
174
- e.stopPropagation();
175
- cancelButton?.onClick ? cancelButton.onClick() : handleClose();
176
- }}
177
- type="button"
178
- />
179
- {additionalButton && (
180
- <Button
181
- label={additionalButton.label}
182
- icon={additionalButton.icon}
183
- onClick={
184
- !!additionalButton.onClick
185
- ? e => {
186
- e.stopPropagation();
187
- additionalButton.onClick!();
188
- !additionalButton.keepOpen && handleClose();
189
- }
190
- : undefined
191
- }
192
- type="button"
193
- variant={additionalButton.variant ?? 'outlined'}
194
- color={additionalButton.color}
195
- disabled={additionalButton.disabled}
196
- />
197
- )}
198
- {confirmButton && (
199
- <Button
200
- label={confirmButton.label || 'Potvrdi'}
201
- icon={confirmButton.icon}
202
- variant="solid"
203
- type={confirmButton.onFormSubmit ? 'submit' : 'button'}
204
- onClick={
205
- !!confirmButton.onClick
206
- ? e => {
207
- e.stopPropagation();
208
- confirmButton.onClick!();
209
- !confirmButton.keepOpen && handleClose();
210
- }
211
- : undefined
212
- }
213
- color={type === 'danger' ? 'danger' : undefined}
214
- disabled={confirmButton.disabled}
215
- />
216
- )}
217
- </div>
147
+ {footer && (
148
+ <DialogFooter
149
+ {...footer}
150
+ onClose={onClose}
151
+ isForm={!!onFormSubmit}
152
+ type={type}
153
+ />
218
154
  )}
219
155
  </ConditionalWrapper>
220
156
  </div>
@@ -0,0 +1,92 @@
1
+ import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2
+ import type { ButtonHTMLAttributes, FC } from 'react';
3
+ import { Button, IButtonColor } from '../../Button/Button';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { IInfoType } from '../../../types/IInfo';
6
+
7
+ export interface IDialogFooterActions {
8
+ confirmButton: {
9
+ label?: string;
10
+ icon?: IconDefinition;
11
+ onClick?: () => void;
12
+ disabled?: boolean;
13
+ keepOpen?: boolean;
14
+ color?: IButtonColor;
15
+ isKeyboardDisabled?: boolean;
16
+ type?: ButtonHTMLAttributes<HTMLButtonElement>['type'];
17
+ };
18
+ cancelButton?: {
19
+ label?: string;
20
+ icon?: IconDefinition;
21
+ onClick?: () => void;
22
+ hidden?: boolean;
23
+ };
24
+ additionalButton?: {
25
+ label: string;
26
+ icon?: IconDefinition;
27
+ onClick: () => void;
28
+ disabled?: boolean;
29
+ keepOpen?: boolean;
30
+ color?: IButtonColor;
31
+ };
32
+ }
33
+
34
+ interface Props extends IDialogFooterActions {
35
+ onClose: () => void;
36
+ isForm?: boolean;
37
+ type?: IInfoType;
38
+ }
39
+
40
+ export const DialogFooter: FC<Props> = ({
41
+ confirmButton,
42
+ cancelButton,
43
+ additionalButton,
44
+ onClose,
45
+ isForm,
46
+ type,
47
+ }) => {
48
+ const { t } = useTranslation();
49
+
50
+ return (
51
+ <div className="iui-dialog-actions">
52
+ {additionalButton && (
53
+ <Button
54
+ {...additionalButton}
55
+ onClick={e => {
56
+ e.stopPropagation();
57
+ additionalButton.onClick!();
58
+ !additionalButton.keepOpen && onClose();
59
+ }}
60
+ variant="simple"
61
+ className="mr-auto"
62
+ />
63
+ )}
64
+ {!cancelButton?.hidden && (
65
+ <Button
66
+ label={cancelButton?.label ?? t('Cancel')}
67
+ icon={cancelButton?.icon}
68
+ variant="outlined"
69
+ onClick={e => {
70
+ e.stopPropagation();
71
+ cancelButton?.onClick?.();
72
+ onClose();
73
+ }}
74
+ type="button"
75
+ />
76
+ )}
77
+ <Button
78
+ label={confirmButton.label || t('Confirm')}
79
+ icon={confirmButton.icon}
80
+ variant="solid"
81
+ type={confirmButton.type ?? (isForm ? 'submit' : 'button')}
82
+ onClick={e => {
83
+ e.stopPropagation();
84
+ confirmButton.onClick?.();
85
+ !confirmButton.keepOpen && !isForm && onClose();
86
+ }}
87
+ color={(confirmButton.color ?? type === 'danger') ? 'danger' : undefined}
88
+ disabled={confirmButton.disabled}
89
+ />
90
+ </div>
91
+ );
92
+ };
@@ -18,13 +18,14 @@ export const useDialogKeyboard = ({
18
18
  useEffect(() => {
19
19
  if (isOpen && !isDisabled) {
20
20
  const handleKeyDown = (event: KeyboardEvent) => {
21
+ event.stopPropagation();
21
22
  const actions: IKeyboardAction[] = [
22
- { key: 'Enter', onAction: submit.onEnter!, disabled: submit.isDisabled },
23
- { key: 'Escape', onAction: onClose },
23
+ { code: 'Enter', onAction: submit.onEnter!, disabled: submit.isDisabled },
24
+ { code: 'Escape', onAction: onClose },
24
25
  ];
25
26
 
26
27
  actions.forEach(item => {
27
- if (!item.disabled && item.key === event.key) {
28
+ if (!item.disabled && item.code === event.key) {
28
29
  event.preventDefault();
29
30
  event.stopPropagation();
30
31
  item.onAction();
@@ -32,9 +33,9 @@ export const useDialogKeyboard = ({
32
33
  });
33
34
  };
34
35
 
35
- window.addEventListener('keydown', handleKeyDown);
36
+ document.addEventListener('keydown', handleKeyDown);
36
37
  return () => {
37
- window.removeEventListener('keydown', handleKeyDown);
38
+ document.removeEventListener('keydown', handleKeyDown);
38
39
  };
39
40
  }
40
41
  }, [isOpen, submit, onClose, isDisabled]);
@@ -21,7 +21,7 @@ export const Header: FC<Props> = ({
21
21
  }) => (
22
22
  <div className="iui-header">
23
23
  {modulesProps && <ModuleSelect {...modulesProps} />}
24
- {customTitle && <h3 className="p-3">{customTitle}</h3>}
24
+ {customTitle && <h3 className="ml-3">{customTitle}</h3>}
25
25
  <div className="flex gap-2 align-center">
26
26
  {children}
27
27
  {/* {!hideNotifications && <Notifications />} */}