@reykjavik/hanna-react 0.10.167 → 0.10.169
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 +19 -0
- package/Modal.js +13 -10
- package/Multiselect.js +1 -0
- package/_abstract/_AbstractModal.d.ts +0 -6
- package/_abstract/_AbstractModal.js +8 -12
- package/esm/Modal.js +13 -10
- package/esm/Multiselect.js +1 -0
- package/esm/_abstract/_AbstractModal.d.ts +0 -6
- package/esm/_abstract/_AbstractModal.js +8 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
+
## 0.10.169
|
|
8
|
+
|
|
9
|
+
_2026-02-24_
|
|
10
|
+
|
|
11
|
+
- `Modal`:
|
|
12
|
+
- fix: Togling `open` prop works unreliably in modern React versions
|
|
13
|
+
- `Multiselect`:
|
|
14
|
+
- fix: Stop `'Escape'` key events bubbling and causing side-effects (e.g.
|
|
15
|
+
closing a parent `Modal`)
|
|
16
|
+
|
|
17
|
+
## 0.10.168
|
|
18
|
+
|
|
19
|
+
_2026-02-23_
|
|
20
|
+
|
|
21
|
+
- `Modal`:
|
|
22
|
+
- fix: `children` render function not invoked correctly
|
|
23
|
+
- fix: Drop redundant `visible` flag for the `children` render function —
|
|
24
|
+
(It was always `true`)
|
|
25
|
+
|
|
7
26
|
## 0.10.167
|
|
8
27
|
|
|
9
28
|
_2026-02-17_
|
package/Modal.js
CHANGED
|
@@ -6,16 +6,19 @@ const react_1 = tslib_1.__importDefault(require("react"));
|
|
|
6
6
|
const _AbstractModal_js_1 = require("./_abstract/_AbstractModal.js");
|
|
7
7
|
exports.defaultModalTexts = _AbstractModal_js_1.defaultAbstractModalTexts;
|
|
8
8
|
const Modal = (props) => {
|
|
9
|
-
const { bling, render,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
const { bling, render, // eslint-disable-line deprecation/deprecation
|
|
10
|
+
children, } = props;
|
|
11
|
+
return (react_1.default.createElement(_AbstractModal_js_1.AbstractModal, Object.assign({}, props, { bem: "Modal", render: undefined }), (renderProps) => {
|
|
12
|
+
const _children = render
|
|
13
|
+
? render(renderProps)
|
|
14
|
+
: typeof children === 'function'
|
|
15
|
+
? children(renderProps)
|
|
16
|
+
: children;
|
|
17
|
+
return bling ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
18
|
+
_children,
|
|
19
|
+
react_1.default.createElement("div", { className: "Modal__blings" },
|
|
20
|
+
react_1.default.createElement("div", { className: "Modal__blings__inner" }, bling)))) : (_children);
|
|
21
|
+
}));
|
|
19
22
|
};
|
|
20
23
|
exports.Modal = Modal;
|
|
21
24
|
exports.default = exports.Modal;
|
package/Multiselect.js
CHANGED
|
@@ -98,12 +98,6 @@ export type AbstractModalProps = {
|
|
|
98
98
|
children: ReactNode | ((props: {
|
|
99
99
|
/** Action dispacher that initiates modal closing action */
|
|
100
100
|
closeModal(): void;
|
|
101
|
-
/**
|
|
102
|
-
* Whether the modal is visible or not. The `onOpen` and `onClosed`
|
|
103
|
-
* callbacks are triggered once the modal has become fully visible or
|
|
104
|
-
* fully hidden.
|
|
105
|
-
*/
|
|
106
|
-
visible: boolean;
|
|
107
101
|
}) => ReactNode);
|
|
108
102
|
}> & WrapperElmProps<'div', 'hidden' | 'role'> & SSRSupportProps;
|
|
109
103
|
type AbstractModalProps_private = AbstractModalProps & BemProps<true>;
|
|
@@ -82,17 +82,6 @@ const AbstractModal = (props) => {
|
|
|
82
82
|
}, closeDelay);
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
-
// ---
|
|
86
|
-
// Update open state when props.open changes. Icky but simple.
|
|
87
|
-
const lastPropsOpen = (0, react_1.useRef)(openProp);
|
|
88
|
-
if (openProp !== lastPropsOpen.current && openProp !== open) {
|
|
89
|
-
lastPropsOpen.current = openProp;
|
|
90
|
-
// these update state during render, which aborts the current render
|
|
91
|
-
// and triggers an immediate rerender.
|
|
92
|
-
openProp ? openModal() : closeModal();
|
|
93
|
-
}
|
|
94
|
-
lastPropsOpen.current = openProp;
|
|
95
|
-
// ---
|
|
96
85
|
const closeOnCurtainClick = isFickle &&
|
|
97
86
|
((e) => {
|
|
98
87
|
if (e.target === e.currentTarget) {
|
|
@@ -118,6 +107,13 @@ const AbstractModal = (props) => {
|
|
|
118
107
|
return () => removeFromModalStack(privateDomId);
|
|
119
108
|
}, [] // eslint-disable-line react-hooks/exhaustive-deps
|
|
120
109
|
);
|
|
110
|
+
(0, react_1.useEffect)(() => {
|
|
111
|
+
if (openProp === open) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
openProp ? openModal() : closeModal();
|
|
115
|
+
}, [openProp] // eslint-disable-line react-hooks/exhaustive-deps
|
|
116
|
+
);
|
|
121
117
|
const PortalOrFragment = props.portal !== false ? _Portal_js_1.Portal : react_1.Fragment;
|
|
122
118
|
const closeButtonLabel = txt.closeButtonLabel || txt.closeButton;
|
|
123
119
|
const { onClick, className } = wrapperProps;
|
|
@@ -132,7 +128,7 @@ const AbstractModal = (props) => {
|
|
|
132
128
|
render
|
|
133
129
|
? render({ closeModal })
|
|
134
130
|
: typeof children === 'function'
|
|
135
|
-
? children({ closeModal
|
|
131
|
+
? children({ closeModal })
|
|
136
132
|
: children,
|
|
137
133
|
isBrowser && !props.noCloseButton && (react_1.default.createElement("button", { className: `${bem}__closebutton`, type: "button", onClick: closeModal, "aria-label": closeButtonLabel, "aria-controls": domid, title: closeButtonLabel }, txt.closeButton))),
|
|
138
134
|
isBrowser && react_1.default.createElement(FocusTrap_js_1.FocusTrap, null)))));
|
package/esm/Modal.js
CHANGED
|
@@ -2,15 +2,18 @@ import React from 'react';
|
|
|
2
2
|
import { AbstractModal, defaultAbstractModalTexts, } from './_abstract/_AbstractModal.js';
|
|
3
3
|
export const defaultModalTexts = defaultAbstractModalTexts;
|
|
4
4
|
export const Modal = (props) => {
|
|
5
|
-
const { bling, render,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
const { bling, render, // eslint-disable-line deprecation/deprecation
|
|
6
|
+
children, } = props;
|
|
7
|
+
return (React.createElement(AbstractModal, Object.assign({}, props, { bem: "Modal", render: undefined }), (renderProps) => {
|
|
8
|
+
const _children = render
|
|
9
|
+
? render(renderProps)
|
|
10
|
+
: typeof children === 'function'
|
|
11
|
+
? children(renderProps)
|
|
12
|
+
: children;
|
|
13
|
+
return bling ? (React.createElement(React.Fragment, null,
|
|
14
|
+
_children,
|
|
15
|
+
React.createElement("div", { className: "Modal__blings" },
|
|
16
|
+
React.createElement("div", { className: "Modal__blings__inner" }, bling)))) : (_children);
|
|
17
|
+
}));
|
|
15
18
|
};
|
|
16
19
|
export default Modal;
|
package/esm/Multiselect.js
CHANGED
|
@@ -98,12 +98,6 @@ export type AbstractModalProps = {
|
|
|
98
98
|
children: ReactNode | ((props: {
|
|
99
99
|
/** Action dispacher that initiates modal closing action */
|
|
100
100
|
closeModal(): void;
|
|
101
|
-
/**
|
|
102
|
-
* Whether the modal is visible or not. The `onOpen` and `onClosed`
|
|
103
|
-
* callbacks are triggered once the modal has become fully visible or
|
|
104
|
-
* fully hidden.
|
|
105
|
-
*/
|
|
106
|
-
visible: boolean;
|
|
107
101
|
}) => ReactNode);
|
|
108
102
|
}> & WrapperElmProps<'div', 'hidden' | 'role'> & SSRSupportProps;
|
|
109
103
|
type AbstractModalProps_private = AbstractModalProps & BemProps<true>;
|
|
@@ -78,17 +78,6 @@ export const AbstractModal = (props) => {
|
|
|
78
78
|
}, closeDelay);
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
|
-
// ---
|
|
82
|
-
// Update open state when props.open changes. Icky but simple.
|
|
83
|
-
const lastPropsOpen = useRef(openProp);
|
|
84
|
-
if (openProp !== lastPropsOpen.current && openProp !== open) {
|
|
85
|
-
lastPropsOpen.current = openProp;
|
|
86
|
-
// these update state during render, which aborts the current render
|
|
87
|
-
// and triggers an immediate rerender.
|
|
88
|
-
openProp ? openModal() : closeModal();
|
|
89
|
-
}
|
|
90
|
-
lastPropsOpen.current = openProp;
|
|
91
|
-
// ---
|
|
92
81
|
const closeOnCurtainClick = isFickle &&
|
|
93
82
|
((e) => {
|
|
94
83
|
if (e.target === e.currentTarget) {
|
|
@@ -114,6 +103,13 @@ export const AbstractModal = (props) => {
|
|
|
114
103
|
return () => removeFromModalStack(privateDomId);
|
|
115
104
|
}, [] // eslint-disable-line react-hooks/exhaustive-deps
|
|
116
105
|
);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (openProp === open) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
openProp ? openModal() : closeModal();
|
|
111
|
+
}, [openProp] // eslint-disable-line react-hooks/exhaustive-deps
|
|
112
|
+
);
|
|
117
113
|
const PortalOrFragment = props.portal !== false ? Portal : Fragment;
|
|
118
114
|
const closeButtonLabel = txt.closeButtonLabel || txt.closeButton;
|
|
119
115
|
const { onClick, className } = wrapperProps;
|
|
@@ -128,7 +124,7 @@ export const AbstractModal = (props) => {
|
|
|
128
124
|
render
|
|
129
125
|
? render({ closeModal })
|
|
130
126
|
: typeof children === 'function'
|
|
131
|
-
? children({ closeModal
|
|
127
|
+
? children({ closeModal })
|
|
132
128
|
: children,
|
|
133
129
|
isBrowser && !props.noCloseButton && (React.createElement("button", { className: `${bem}__closebutton`, type: "button", onClick: closeModal, "aria-label": closeButtonLabel, "aria-controls": domid, title: closeButtonLabel }, txt.closeButton))),
|
|
134
130
|
isBrowser && React.createElement(FocusTrap, null)))));
|