foris 6.1.1 → 6.2.0

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.
@@ -5,10 +5,12 @@
5
5
  * See /LICENSE for more information.
6
6
  */
7
7
 
8
- import React from "react";
8
+ import React, { useRef } from "react";
9
9
 
10
10
  import PropTypes from "prop-types";
11
11
 
12
+ import { useFocusTrap } from "../utils/hooks";
13
+
12
14
  export const ALERT_TYPES = Object.freeze({
13
15
  PRIMARY: "primary",
14
16
  SECONDARY: "secondary",
@@ -37,11 +39,15 @@ Alert.defaultProps = {
37
39
  };
38
40
 
39
41
  function Alert({ type, onDismiss, children }) {
42
+ const alertRef = useRef();
43
+ useFocusTrap(alertRef, !!onDismiss);
40
44
  return (
41
45
  <div
46
+ ref={alertRef}
42
47
  className={`alert alert-${type} ${
43
48
  onDismiss ? "alert-dismissible" : ""
44
49
  }`.trim()}
50
+ role="alert"
45
51
  >
46
52
  {onDismiss && (
47
53
  <button
@@ -9,7 +9,7 @@ import React, { useRef, useEffect } from "react";
9
9
 
10
10
  import PropTypes from "prop-types";
11
11
 
12
- import { useClickOutside } from "../utils/hooks";
12
+ import { useClickOutside, useFocusTrap } from "../utils/hooks";
13
13
  import Portal from "../utils/Portal";
14
14
  import "./Modal.css";
15
15
 
@@ -29,10 +29,11 @@ Modal.propTypes = {
29
29
  };
30
30
 
31
31
  export function Modal({ shown, setShown, scrollable, size, children }) {
32
- const dialogRef = useRef();
32
+ const modalRef = useRef();
33
33
  let modalSize = "modal-";
34
34
 
35
- useClickOutside(dialogRef, () => setShown(false));
35
+ useClickOutside(modalRef, () => setShown(false));
36
+ useFocusTrap(modalRef, shown);
36
37
 
37
38
  useEffect(() => {
38
39
  const handleEsc = (event) => {
@@ -65,11 +66,13 @@ export function Modal({ shown, setShown, scrollable, size, children }) {
65
66
  return (
66
67
  <Portal containerId="modal-container">
67
68
  <div
69
+ ref={modalRef}
68
70
  className={`modal fade ${shown ? "show" : ""}`.trim()}
69
71
  role="dialog"
72
+ aria-modal="true"
73
+ aria-labelledby="modal-title"
70
74
  >
71
75
  <div
72
- ref={dialogRef}
73
76
  className={`${modalSize.trim()} modal-dialog modal-dialog-centered ${
74
77
  scrollable ? "modal-dialog-scrollable" : ""
75
78
  }`.trim()}
@@ -90,7 +93,7 @@ ModalHeader.propTypes = {
90
93
  export function ModalHeader({ setShown, title }) {
91
94
  return (
92
95
  <div className="modal-header">
93
- <h5 className="modal-title">{title}</h5>
96
+ <h1 className="modal-title fs-5">{title}</h1>
94
97
  <button
95
98
  type="button"
96
99
  className="btn-close"
@@ -9,7 +9,7 @@
9
9
  .spinner-wrapper .spinner-border {
10
10
  width: 4rem;
11
11
  height: 4rem;
12
- color: #00a2e2;
12
+ color: var(--bs-primary);
13
13
  }
14
14
 
15
15
  .spinner-fs-background {
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foris",
3
- "version": "6.1.1",
3
+ "version": "6.2.0",
4
4
  "description": "Foris JS library is a set of components and utils for reForis application and plugins.",
5
5
  "author": "CZ.NIC, z.s.p.o.",
6
6
  "repository": {
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
3
  *
4
4
  * This is free software, licensed under the GNU General Public License v3.
5
5
  * See /LICENSE for more information.
@@ -9,8 +9,10 @@ export const REFORIS_URL_PREFIX = "/reforis";
9
9
  export const REFORIS_API_URL_PREFIX = `${REFORIS_URL_PREFIX}/api`;
10
10
 
11
11
  export const ForisURLs = {
12
+ // turris-auth
12
13
  login: `/login?${REFORIS_URL_PREFIX}/`,
13
14
  logout: `/logout`,
15
+ extendSession: `/extend-session`,
14
16
 
15
17
  static: `${REFORIS_URL_PREFIX}/static/reforis`,
16
18
  wifi: `${REFORIS_URL_PREFIX}/network-settings/wifi`,
package/utils/hooks.js CHANGED
@@ -40,3 +40,40 @@ export function useClickOutside(element, callback) {
40
40
  };
41
41
  });
42
42
  }
43
+
44
+ /* Trap focus inside element. */
45
+ export function useFocusTrap(elementRef, condition = true) {
46
+ useEffect(() => {
47
+ if (!condition) {
48
+ return;
49
+ }
50
+ const currentElement = elementRef.current;
51
+ const focusableElements = currentElement.querySelectorAll(
52
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
53
+ );
54
+ const firstElement = focusableElements[0];
55
+ const lastElement = focusableElements[focusableElements.length - 1];
56
+
57
+ const handleTab = (event) => {
58
+ if (event.key === "Tab") {
59
+ if (event.shiftKey) {
60
+ if (document.activeElement === firstElement) {
61
+ lastElement.focus();
62
+ event.preventDefault();
63
+ }
64
+ } else if (document.activeElement === lastElement) {
65
+ firstElement.focus();
66
+ event.preventDefault();
67
+ }
68
+ }
69
+ };
70
+
71
+ currentElement.addEventListener("keydown", handleTab);
72
+
73
+ firstElement.focus();
74
+
75
+ return () => {
76
+ currentElement.removeEventListener("keydown", handleTab);
77
+ };
78
+ }, [elementRef, condition]);
79
+ }
package/foris-6.1.1.tgz DELETED
Binary file