@orangesk/orange-design-system 2.0.0-beta.26 → 2.0.0-beta.28
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/build/components/index.js +1 -1
- package/build/components/index.js.map +1 -1
- package/build/components/tsconfig.tsbuildinfo +1 -1
- package/build/components/types/index.d.ts +2 -2
- package/build/components/types/src/components/Modal/Modal.d.ts +2 -2
- package/build/components/types/src/components/Modal/Modal.static.d.ts +2 -1
- package/build/lib/scripts.js +1 -1
- package/build/lib/scripts.js.map +1 -1
- package/build/lib/tsconfig.tsbuildinfo +1 -1
- package/build/search-index.json +1 -1
- package/package.json +3 -3
- package/src/components/Modal/Modal.static.ts +49 -52
- package/src/components/Modal/Modal.tsx +34 -12
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React, { useEffect } from "react";
|
|
3
|
+
import React, { useEffect, useMemo } from "react";
|
|
4
4
|
import cx from "classnames";
|
|
5
5
|
|
|
6
6
|
import { useStatic } from "../../utils/hooks";
|
|
7
7
|
import ConditionalWrapper from "../../utils/ConditionalWrapper";
|
|
8
8
|
import { Button } from "../Button";
|
|
9
9
|
import { Buttons } from "../Buttons";
|
|
10
|
-
|
|
11
|
-
// Use JavaScript version for now, then convert to TypeScript later
|
|
12
10
|
import ModalStatic from "./Modal.static";
|
|
13
11
|
import { ModalCloseButton } from "./ModalCloseButton";
|
|
14
12
|
import { ModalTitle } from "./ModalTitle";
|
|
@@ -31,8 +29,8 @@ interface ModalProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
31
29
|
id: string;
|
|
32
30
|
/** isActive controls if modal is opened or closed */
|
|
33
31
|
isActive?: boolean;
|
|
34
|
-
/**
|
|
35
|
-
|
|
32
|
+
/** Callback fired when modal is closed */
|
|
33
|
+
onHide?: () => void;
|
|
36
34
|
/** Custom header renderer. Receives id as function param. Returned element(s) must contain a header with close button. */
|
|
37
35
|
renderHeader?: (id: string) => React.ReactNode;
|
|
38
36
|
/** Custom body renderer. Receives title as function param. Returned element(s) must contain a title. */
|
|
@@ -61,7 +59,6 @@ const defaultProps = {
|
|
|
61
59
|
Zatvoriť
|
|
62
60
|
</Button>,
|
|
63
61
|
],
|
|
64
|
-
noInit: false,
|
|
65
62
|
};
|
|
66
63
|
|
|
67
64
|
const Modal: React.FC<ModalProps> = ({
|
|
@@ -70,8 +67,8 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
70
67
|
children,
|
|
71
68
|
hasStickyFooter,
|
|
72
69
|
id,
|
|
73
|
-
noInit = defaultProps.noInit,
|
|
74
70
|
isActive,
|
|
71
|
+
onHide,
|
|
75
72
|
size,
|
|
76
73
|
title,
|
|
77
74
|
renderHeader,
|
|
@@ -83,12 +80,38 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
83
80
|
disableFooterSpacing,
|
|
84
81
|
...other
|
|
85
82
|
}) => {
|
|
86
|
-
|
|
83
|
+
// In React controlled mode (using isActive), we skip data-modal
|
|
84
|
+
// so vanilla JS won't initialize and move modal to #root-modals
|
|
85
|
+
// onHide alone works in uncontrolled mode - it's just a callback
|
|
86
|
+
const isReactControlled = isActive !== undefined;
|
|
87
|
+
|
|
88
|
+
const modalConfig = useMemo(
|
|
89
|
+
() => (isReactControlled ? { disablePortal: true } : {}),
|
|
90
|
+
[isReactControlled],
|
|
91
|
+
);
|
|
87
92
|
const [modalRef, instance] = useStatic(ModalStatic, modalConfig);
|
|
88
93
|
|
|
89
94
|
useEffect(() => {
|
|
90
|
-
if (
|
|
91
|
-
|
|
95
|
+
if (!instance.current || !onHide) return;
|
|
96
|
+
|
|
97
|
+
const handleHide = () => {
|
|
98
|
+
onHide();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
instance.current.instance.on("hide", handleHide);
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
instance.current?.instance.off("hide", handleHide);
|
|
105
|
+
};
|
|
106
|
+
}, [instance, onHide]);
|
|
107
|
+
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (!instance.current) return;
|
|
110
|
+
|
|
111
|
+
if (isActive) {
|
|
112
|
+
instance.current.show();
|
|
113
|
+
} else if (isActive === false) {
|
|
114
|
+
instance.current.hide();
|
|
92
115
|
}
|
|
93
116
|
}, [instance, isActive]);
|
|
94
117
|
|
|
@@ -114,7 +137,7 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
114
137
|
return (
|
|
115
138
|
<div
|
|
116
139
|
id={id}
|
|
117
|
-
data-modal
|
|
140
|
+
{...(!isReactControlled && { "data-modal": true })}
|
|
118
141
|
className={CLASS_ROOT}
|
|
119
142
|
ref={modalRef}
|
|
120
143
|
role="dialog"
|
|
@@ -124,7 +147,6 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
124
147
|
>
|
|
125
148
|
<div className="modal__overlay" tabIndex={-1} data-a11y-dialog-hide />
|
|
126
149
|
<div className={dialogClasses} role="document" {...other}>
|
|
127
|
-
{}
|
|
128
150
|
<div
|
|
129
151
|
className={cx(`${CLASS_ROOT}__header`, {
|
|
130
152
|
[`${CLASS_ROOT}__header--no-spacing`]: disableHeaderSpacing,
|