typescript-overlay-essentials 1.5.0 → 1.6.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.
@@ -37,9 +37,7 @@ export function ConfirmationBox({ state, setState }) {
37
37
  var _a, _b, _c;
38
38
  // Wird verwendet um die Confirmation Boxen ein- und auszublenden
39
39
  const [showConfirm, setShowConfirm] = useState(false);
40
- // Damit der Fokus auf die Confirmation Box gesetzt wird, wenn sie geöffnet wird
41
- // Und man sie mit Enter bestätigen kann
42
- const overlayRef = useRef(null);
40
+ const confirmButtonRef = useRef(null);
43
41
  // Sobald der State von außen aktualisiert wird triggert diese Funktion
44
42
  // Die setzt showConfirm auf true (oder ruft die übergebene Funktion auf wenn confirmationBoxen disabled sind)
45
43
  useEffect(() => {
@@ -47,6 +45,7 @@ export function ConfirmationBox({ state, setState }) {
47
45
  if (state === null || state === void 0 ? void 0 : state.handlerOk) {
48
46
  if ((_a = state.activateConfirm) !== null && _a !== void 0 ? _a : true) {
49
47
  setShowConfirm(true);
48
+ setTimeout(() => { var _a; (_a = confirmButtonRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
50
49
  }
51
50
  else {
52
51
  // Wenn activateConfirm explizit false ist, dann wird die übergebene Funktion direkt ausgeführt ohne ConfirmationBox
@@ -54,10 +53,6 @@ export function ConfirmationBox({ state, setState }) {
54
53
  state.handlerOk(state.handlerArgs);
55
54
  }
56
55
  }
57
- setTimeout(() => {
58
- var _a;
59
- (_a = overlayRef.current) === null || _a === void 0 ? void 0 : _a.focus();
60
- }, 0);
61
56
  }, [state]);
62
57
  const handleAction = (handler) => {
63
58
  setShowConfirm(false);
@@ -70,22 +65,10 @@ export function ConfirmationBox({ state, setState }) {
70
65
  tempState.handler(tempState.handlerArgs);
71
66
  };
72
67
  return showConfirm ?
73
- _jsx("div", { className: "confirmation-overlay", tabIndex: 0, ref: overlayRef, children: _jsxs("div", { className: "confirmation-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, children: [state.addCloseButton ?
74
- _jsx("span", { className: "closeButton", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", tabIndex: 0, className: "close-icon", onClick: () => handleAction(undefined), onKeyDown: (e) => {
75
- if (e.key === 'Enter' || e.key === ' ') {
76
- e.preventDefault(); // Verhindert Scroll bei Space
77
- handleAction(undefined);
78
- }
79
- }, role: "button", "aria-label": "Dialog schlie\u00DFen", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) }) :
80
- _jsx(_Fragment, {}), (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? _jsx("div", { className: "headline", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: state === null || state === void 0 ? void 0 : state.headline }) }) : _jsx(_Fragment, {}), _jsx("div", { style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (_b = (_a = state.message1) !== null && _a !== void 0 ? _a : state.message) !== null && _b !== void 0 ? _b : "" }), _jsx("div", { style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (_c = state.message2) !== null && _c !== void 0 ? _c : "" }) }), _jsxs("div", { className: "confirmation-buttons", children: [_jsx("button", { onClick: () => handleAction(state.handlerCancel), onKeyDown: (e) => {
81
- if (e.key === 'Enter' || e.key === ' ') {
82
- e.preventDefault(); // Verhindert Scroll bei Space
83
- handleAction(state.handlerCancel);
84
- }
85
- }, className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) !== undefined ? state.cancelButtonStyle : {}, children: state.cancelButtonText ? state.cancelButtonText : "Abbrechen" }), _jsx("button", { onClick: () => handleAction(state.handlerOk), id: "confirmButton", onKeyDown: (e) => {
86
- if (e.key === 'Enter' || e.key === ' ') {
87
- e.preventDefault(); // Verhindert Scroll bei Space
88
- handleAction(state.handlerOk);
89
- }
90
- }, className: "px-4 py-2 bg-blue-600 text-white rounded", style: (state === null || state === void 0 ? void 0 : state.proceedButtonStyle) !== undefined ? state.proceedButtonStyle : {}, children: state.proceedButtonText ? state.proceedButtonText : "OK" })] })] }) }) : _jsx(_Fragment, {});
68
+ _jsx("div", { className: "confirmation-overlay", children: _jsxs("div", { className: "confirmation-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, role: "alertdialog", "aria-modal": "true", "aria-labelledby": (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? "confirmation-headline" : undefined, "aria-label": (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? undefined : "Bestätigung", "aria-describedby": "confirmation-message", onKeyDown: (event) => {
69
+ if (event.key === "Escape")
70
+ handleAction(state.handlerCancel);
71
+ }, children: [state.addCloseButton ?
72
+ _jsx("span", { className: "closeButton", children: _jsx("button", { type: "button", className: "close-icon", onClick: () => handleAction(undefined), "aria-label": "Dialog schlie\u00DFen", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) }) }) :
73
+ _jsx(_Fragment, {}), (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? _jsx("div", { className: "headline", id: "confirmation-headline", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: state === null || state === void 0 ? void 0 : state.headline }) }) : _jsx(_Fragment, {}), _jsx("div", { id: "confirmation-message", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (_b = (_a = state.message1) !== null && _a !== void 0 ? _a : state.message) !== null && _b !== void 0 ? _b : "" }), _jsx("div", { style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (_c = state.message2) !== null && _c !== void 0 ? _c : "" }) }), _jsxs("div", { className: "confirmation-buttons", children: [_jsx("button", { onClick: () => handleAction(state.handlerCancel), type: "button", className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) !== undefined ? state.cancelButtonStyle : {}, children: state.cancelButtonText ? state.cancelButtonText : "Abbrechen" }), _jsx("button", { onClick: () => handleAction(state.handlerOk), ref: confirmButtonRef, type: "button", className: "px-4 py-2 bg-blue-600 text-white rounded", style: (state === null || state === void 0 ? void 0 : state.proceedButtonStyle) !== undefined ? state.proceedButtonStyle : {}, children: state.proceedButtonText ? state.proceedButtonText : "OK" })] })] }) }) : _jsx(_Fragment, {});
91
74
  }
package/dist/Dropdown.js CHANGED
@@ -46,7 +46,7 @@ export function Dropdown({ selections, value, onChange, maxMenuHeight, menuPlace
46
46
  function hasId(value) {
47
47
  return typeof value === "object" && value !== null && "id" in value;
48
48
  }
49
- return isMulti || Array.isArray(defaultValue) ? (_jsx(Select, { className: "custom-select", isMulti: true, placeholder: placeHolder !== null && placeHolder !== void 0 ? placeHolder : "", options: options, value: options.length > 0 && hasId(options[0].value) ? // Wenn die values der Optionen ids haben, handelt es sich um komplexe Objekte, die zur Auswahl stehen und müssen dahingehend verglichen werden
49
+ return isMulti || Array.isArray(defaultValue) ? (_jsx(Select, { className: "custom-select", isMulti: true, "aria-label": placeHolder !== null && placeHolder !== void 0 ? placeHolder : "Auswahl", placeholder: placeHolder !== null && placeHolder !== void 0 ? placeHolder : "", options: options, value: options.length > 0 && hasId(options[0].value) ? // Wenn die values der Optionen ids haben, handelt es sich um komplexe Objekte, die zur Auswahl stehen und müssen dahingehend verglichen werden
50
50
  options.filter(opt => (hasId(opt.value) && value.find(val => hasId(val) && hasId(opt.value) && val.id === opt.value.id))) // Dann alle Optionen, die in den values per id vorkommen
51
51
  : options.filter(opt => (value.includes(opt.value))) // Ansonsten einfach alle Optionen, die in den values vorkommen
52
52
  , onChange: (selectedOption) => { initializedRef.current = true; onChange(selectedOption.map((opt) => opt.value)); }, maxMenuHeight: maxMenuHeight !== null && maxMenuHeight !== void 0 ? maxMenuHeight : 280, menuPlacement: menuPlacement !== null && menuPlacement !== void 0 ? menuPlacement : "auto", menuPosition: "fixed", classNamePrefix: "dropdown", defaultValue: options.filter(opt => defaultValue.map(({ value }) => (value)).includes(opt.value)), formatOptionLabel: ({ label, indent }, { context }) => {
@@ -92,7 +92,7 @@ export function Dropdown({ selections, value, onChange, maxMenuHeight, menuPlace
92
92
  isDarkMode ? (cardColorVariant ? 'white' : 'white') : cardColorVariant ? 'black' : 'var(--FastSchwarz, black)',
93
93
  cursor: 'pointer',
94
94
  }),
95
- }, ...rest })) : (_jsx(Select, { className: "custom-select", isMulti: false, placeholder: placeHolder !== null && placeHolder !== void 0 ? placeHolder : "", options: options, value: options.length > 0 && hasId(options[0].value) ? // Wenn die values der Optionen ids haben, handelt es sich um komplexe Objekte, die zur Auswahl stehen und müssen dahingehend verglichen werden
95
+ }, ...rest })) : (_jsx(Select, { className: "custom-select", isMulti: false, "aria-label": placeHolder !== null && placeHolder !== void 0 ? placeHolder : "Auswahl", placeholder: placeHolder !== null && placeHolder !== void 0 ? placeHolder : "", options: options, value: options.length > 0 && hasId(options[0].value) ? // Wenn die values der Optionen ids haben, handelt es sich um komplexe Objekte, die zur Auswahl stehen und müssen dahingehend verglichen werden
96
96
  options.find(opt => hasId(opt.value) && hasId(value) && opt.value.id === value.id) // Die eine Option mit der passenden id finden
97
97
  : options.find(opt => opt.value === value), onChange: (selectedOption) => { var _a; return onChange((_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.value) !== null && _a !== void 0 ? _a : undefined); }, maxMenuHeight: maxMenuHeight !== null && maxMenuHeight !== void 0 ? maxMenuHeight : 280, menuPlacement: menuPlacement !== null && menuPlacement !== void 0 ? menuPlacement : "auto", menuPosition: "fixed", classNamePrefix: "dropdown", defaultValue: defaultValue, formatOptionLabel: ({ label, indent }, { context }) => {
98
98
  if (context === 'menu') {
@@ -27,7 +27,6 @@ export function InfoOverlay({ state, setState }) {
27
27
  useEffect(() => {
28
28
  if ((state === null || state === void 0 ? void 0 : state.message) !== undefined || (state === null || state === void 0 ? void 0 : state.headline) !== undefined) {
29
29
  setShowOverlay(true);
30
- setTimeout(() => { var _a; (_a = document.getElementById("infoButton")) === null || _a === void 0 ? void 0 : _a.focus(); }, 5);
31
30
  }
32
31
  }, [state]);
33
32
  const handleAction = () => {
@@ -41,14 +40,15 @@ export function InfoOverlay({ state, setState }) {
41
40
  tempState.handler(tempState.handlerArgs);
42
41
  };
43
42
  return showOverlay ?
44
- _jsx("div", { className: "information-overlay", tabIndex: 0, children: _jsxs("div", { className: "information-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, children: [state.addCloseButton ?
43
+ _jsx("div", { className: "information-overlay", children: _jsxs("div", { className: "information-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, role: "dialog", "aria-modal": "true", "aria-labelledby": (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? "information-headline" : undefined, "aria-label": (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? undefined : "Information", "aria-describedby": "information-message", onKeyDown: (event) => { if (event.key === "Escape")
44
+ handleAction(); }, children: [state.addCloseButton ?
45
45
  _jsx("span", { className: "closeButton", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", tabIndex: 0, className: "close-icon", onClick: () => setShowOverlay(false), onKeyDown: (e) => {
46
46
  if (e.key === 'Enter' || e.key === ' ') {
47
47
  e.preventDefault(); // Verhindert Scroll bei Space
48
48
  setShowOverlay(false);
49
49
  }
50
50
  }, role: "button", "aria-label": "Dialog schlie\u00DFen", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) }) :
51
- _jsx(_Fragment, {}), _jsx("div", { className: "headline", tabIndex: 0, style: { whiteSpace: "pre-line" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? state.headline : "" }) }), _jsx("div", { tabIndex: 0, style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) !== undefined ? state.message : "" }), _jsx("div", { className: "information-buttons", children: _jsx("button", { onClick: () => handleAction(), onKeyDown: (e) => {
51
+ _jsx(_Fragment, {}), _jsx("div", { className: "headline", id: "information-headline", style: { whiteSpace: "pre-line" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) !== undefined ? state.headline : "" }) }), _jsx("div", { id: "information-message", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) !== undefined ? state.message : "" }), _jsx("div", { className: "information-buttons", children: _jsx("button", { type: "button", autoFocus: true, onClick: () => handleAction(), onKeyDown: (e) => {
52
52
  if (e.key === 'Enter' || e.key === ' ') {
53
53
  e.preventDefault(); // Verhindert Scroll bei Space
54
54
  handleAction();
@@ -44,7 +44,6 @@ export function InfoOverlayWithInput({ state, setState }) {
44
44
  if ((state === null || state === void 0 ? void 0 : state.message) != null || (state === null || state === void 0 ? void 0 : state.headline) != null) {
45
45
  setInput((state === null || state === void 0 ? void 0 : state.preInput) != null ? state.preInput : "");
46
46
  setShowOverlay(true);
47
- setTimeout(() => { var _a; (_a = document.getElementById("information-inputfield")) === null || _a === void 0 ? void 0 : _a.focus(); }, 1);
48
47
  }
49
48
  }, [state]);
50
49
  // Sorgt dafür, dass die Eingabe beim tippen aktualisiert wird
@@ -70,14 +69,15 @@ export function InfoOverlayWithInput({ state, setState }) {
70
69
  tempState.handler(tempState.handlerArgs);
71
70
  };
72
71
  return showOverlay ?
73
- _jsx("div", { className: "information-overlay-with-input", children: _jsxs("div", { className: "information-box-with-input", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, children: [state.addCloseButton ?
72
+ _jsx("div", { className: "information-overlay-with-input", children: _jsxs("div", { className: "information-box-with-input", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, role: "dialog", "aria-modal": "true", "aria-labelledby": (state === null || state === void 0 ? void 0 : state.headline) != null ? "information-input-headline" : undefined, "aria-label": (state === null || state === void 0 ? void 0 : state.headline) != null ? undefined : "Information", "aria-describedby": "information-input-message", onKeyDown: (event) => { if (event.key === "Escape")
73
+ handleAction(state.handlerCancel, false); }, children: [state.addCloseButton ?
74
74
  _jsx("span", { className: "closeButton", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", tabIndex: 0, className: "close-icon", onClick: () => handleAction(undefined, false), onKeyDown: (e) => {
75
75
  if (e.key === 'Enter' || e.key === ' ') {
76
76
  e.preventDefault(); // Verhindert Scroll bei Space
77
77
  handleAction(undefined, false);
78
78
  }
79
79
  }, role: "button", "aria-label": "Dialog schlie\u00DFen", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) }) :
80
- _jsx(_Fragment, {}), _jsx("div", { className: "headline", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) != null ? state.headline : "" }) }), _jsx("div", { style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) != null ? state.message : "" }), _jsx("div", { className: "information-input", children: _jsx("input", { id: "information-inputfield", placeholder: (state === null || state === void 0 ? void 0 : state.placeholder) != null ? state.placeholder : "", pattern: "^[A-Za-z0-9_-~]+$", required: true, type: "text", className: "form-control", value: input, onChange: handleInputChange, onKeyDown: handleInputKeyDown, tabIndex: 0 }) }), _jsxs("div", { className: "information-buttons", children: [_jsx("button", { onClick: () => handleAction(state.handlerCancel, false), className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) != null ? state.cancelButtonStyle : {}, tabIndex: 0, onKeyDown: (e) => {
80
+ _jsx(_Fragment, {}), _jsx("div", { className: "headline", id: "information-input-headline", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) != null ? state.headline : "" }) }), _jsx("div", { id: "information-input-message", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) != null ? state.message : "" }), _jsx("div", { className: "information-input", children: _jsx("input", { id: "information-inputfield", "aria-label": (state === null || state === void 0 ? void 0 : state.placeholder) != null ? state.placeholder : "Eingabe", autoFocus: true, placeholder: (state === null || state === void 0 ? void 0 : state.placeholder) != null ? state.placeholder : "", pattern: "^[A-Za-z0-9_-~]+$", required: true, type: "text", className: "form-control", value: input, onChange: handleInputChange, onKeyDown: handleInputKeyDown }) }), _jsxs("div", { className: "information-buttons", children: [_jsx("button", { onClick: () => handleAction(state.handlerCancel, false), className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) != null ? state.cancelButtonStyle : {}, tabIndex: 0, onKeyDown: (e) => {
81
81
  if (e.key === 'Enter' || e.key === ' ') {
82
82
  e.preventDefault(); // Verhindert Scroll bei Space
83
83
  handleAction(state.handlerCancel, false);
@@ -10,6 +10,7 @@ export function setInputFilter(inputFilter, errMsg, textbox) {
10
10
  if (["keydown", "mousedown", "focusout"].indexOf(e.type) >= 0) {
11
11
  target.classList.remove("input-error");
12
12
  target.setCustomValidity("");
13
+ target.removeAttribute("aria-invalid");
13
14
  }
14
15
  target.dataset.oldValue = target.value;
15
16
  target.dataset.oldSelectionStart = (_b = (_a = target.selectionStart) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "";
@@ -16,7 +16,7 @@ export const defaultLoadingOverlayState = {
16
16
  // - showSuccess: zeigt bei "true" ein grünes Häkchen an und bei "false" ein rot hinterlegtes X. Bei "undefined" wird die normale Ladeanimation gezeigt.
17
17
  // - style: ist der Style des LoadingOverlays (Standardmäßig unverändert)
18
18
  export function LoadingOverlay({ state, setState }) {
19
- var _a, _b, _c;
19
+ var _a, _b, _c, _d;
20
20
  // Wird verwendet um das LoadingOverlay ein- und auszublenden
21
21
  const [showOverlay, setShowOverlay] = useState(false);
22
22
  // Sobald der State von außen aktualisiert wird triggert diese Funktion
@@ -30,9 +30,9 @@ export function LoadingOverlay({ state, setState }) {
30
30
  setShowOverlay(false);
31
31
  }
32
32
  }, [state, setState]);
33
- return showOverlay ? (_jsx("div", { className: "loading-overlay", children: _jsxs("div", { className: "loading-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, children: [_jsx("div", { className: "spinner " + (state.showSuccess === undefined ? "is-loading" : (state.showSuccess ? "is-success" : "is-error")), style: {
34
- "--spinner-color": (_a = state.color) !== null && _a !== void 0 ? _a : "#e60028",
35
- "--success-bg": (_b = state.color) !== null && _b !== void 0 ? _b : "#42ab34",
36
- "--error-bg": (_c = state.color) !== null && _c !== void 0 ? _c : "#e60028",
37
- } }), state.message && _jsx("div", { className: "loading-message", children: state.message })] }) })) : _jsx(_Fragment, {});
33
+ return showOverlay ? (_jsx("div", { className: "loading-overlay", role: "status", "aria-live": "polite", "aria-atomic": "true", "aria-busy": (_a = state === null || state === void 0 ? void 0 : state.isActive) !== null && _a !== void 0 ? _a : false, children: _jsxs("div", { className: "loading-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, children: [_jsx("div", { className: "spinner " + (state.showSuccess === undefined ? "is-loading" : (state.showSuccess ? "is-success" : "is-error")), style: {
34
+ "--spinner-color": (_b = state.color) !== null && _b !== void 0 ? _b : "#e60028",
35
+ "--success-bg": (_c = state.color) !== null && _c !== void 0 ? _c : "#42ab34",
36
+ "--error-bg": (_d = state.color) !== null && _d !== void 0 ? _d : "#e60028",
37
+ }, "aria-hidden": "true" }), state.message && _jsx("div", { className: "loading-message", children: state.message })] }) })) : _jsx(_Fragment, {});
38
38
  }
@@ -46,7 +46,6 @@ export function MultipleChoiceOverlay({ state, setState }) {
46
46
  if ((state === null || state === void 0 ? void 0 : state.message) != null || (state === null || state === void 0 ? void 0 : state.headline) != null) {
47
47
  setInput((state === null || state === void 0 ? void 0 : state.preInput) != null ? state.preInput : []);
48
48
  setShowOverlay(true);
49
- setTimeout(() => { var _a; (_a = document.getElementById("confirmButton")) === null || _a === void 0 ? void 0 : _a.focus(); }, 1);
50
49
  }
51
50
  }, [state]);
52
51
  // Toggled die Auswahl eines Choices
@@ -72,14 +71,15 @@ export function MultipleChoiceOverlay({ state, setState }) {
72
71
  tempState.handler(tempState.handlerArgs);
73
72
  };
74
73
  return showOverlay ?
75
- _jsx("div", { className: "multiplechoice-overlay", children: _jsxs("div", { className: "multiplechoice-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, children: [state.addCloseButton ?
74
+ _jsx("div", { className: "multiplechoice-overlay", children: _jsxs("div", { className: "multiplechoice-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, role: "dialog", "aria-modal": "true", "aria-labelledby": (state === null || state === void 0 ? void 0 : state.headline) != null ? "multiple-choice-headline" : undefined, "aria-label": (state === null || state === void 0 ? void 0 : state.headline) != null ? undefined : "Mehrfachauswahl", "aria-describedby": "multiple-choice-message", onKeyDown: (event) => { if (event.key === "Escape")
75
+ handleAction(state.handlerCancel, false); }, children: [state.addCloseButton ?
76
76
  _jsx("span", { className: "closeButton", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", tabIndex: 0, className: "close-icon", onClick: () => handleAction(undefined, false), onKeyDown: (e) => {
77
77
  if (e.key === 'Enter' || e.key === ' ') {
78
78
  e.preventDefault(); // Verhindert Scroll bei Space
79
79
  handleAction(undefined, false);
80
80
  }
81
81
  }, role: "button", "aria-label": "Dialog schlie\u00DFen", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) }) :
82
- _jsx(_Fragment, {}), _jsx("div", { className: "headline", id: "theHeadline", tabIndex: 0, style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) != null ? state.headline : "" }) }), _jsx("div", { tabIndex: 0, style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) != null ? state.message : "" }), _jsx("div", { className: "choices-input", children: _jsx("div", { className: "choices-container", children: state === null || state === void 0 ? void 0 : state.choices.map(choice => {
82
+ _jsx(_Fragment, {}), _jsx("div", { className: "headline", id: "multiple-choice-headline", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) != null ? state.headline : "" }) }), _jsx("div", { id: "multiple-choice-message", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) != null ? state.message : "" }), _jsx("div", { className: "choices-input", role: "group", "aria-label": "Auswahloptionen", children: _jsx("div", { className: "choices-container", children: state === null || state === void 0 ? void 0 : state.choices.map(choice => {
83
83
  var _a;
84
84
  return (_jsxs("label", { className: "choice-label", children: [_jsx("input", { type: "checkbox", checked: input.includes(choice), disabled: (_a = state.disabledChoices) === null || _a === void 0 ? void 0 : _a.includes(choice), onChange: () => toggle(choice), tabIndex: 0, onKeyDown: (e) => {
85
85
  if (e.key === 'Enter' || e.key === ' ') {
@@ -92,7 +92,7 @@ export function MultipleChoiceOverlay({ state, setState }) {
92
92
  event.preventDefault(); // Verhindert Scroll bei Space
93
93
  handleAction(state.handlerCancel, false);
94
94
  }
95
- }, className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) != null ? state.cancelButtonStyle : {}, children: (state === null || state === void 0 ? void 0 : state.cancelButtonText) != null ? state.cancelButtonText : "Abbrechen" }), _jsx("button", { onClick: () => handleAction(state.handlerOk, true), id: "confirmButton", onKeyDown: (event) => {
95
+ }, className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) != null ? state.cancelButtonStyle : {}, children: (state === null || state === void 0 ? void 0 : state.cancelButtonText) != null ? state.cancelButtonText : "Abbrechen" }), _jsx("button", { onClick: () => handleAction(state.handlerOk, true), type: "button", autoFocus: true, onKeyDown: (event) => {
96
96
  if (event.key === "Enter" || event.key === ' ') {
97
97
  event.preventDefault(); // Verhindert Scroll bei Space
98
98
  handleAction(state.handlerOk, true);
@@ -46,7 +46,6 @@ export function MultipleRadioOverlay({ state, setState }) {
46
46
  if ((state === null || state === void 0 ? void 0 : state.message) != null || (state === null || state === void 0 ? void 0 : state.headline) != null) {
47
47
  setInput((state === null || state === void 0 ? void 0 : state.preInput) != null ? state.preInput : "");
48
48
  setShowOverlay(true);
49
- setTimeout(() => { var _a; (_a = document.getElementById("confirmButton")) === null || _a === void 0 ? void 0 : _a.focus(); }, 1);
50
49
  }
51
50
  }, [state]);
52
51
  const handleAction = (handler, useInput) => {
@@ -62,16 +61,17 @@ export function MultipleRadioOverlay({ state, setState }) {
62
61
  tempState.handler(tempState.handlerArgs);
63
62
  };
64
63
  return showOverlay ?
65
- _jsx("div", { className: "multipleradio-overlay", children: _jsxs("div", { className: "multipleradio-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, children: [state.addCloseButton ?
64
+ _jsx("div", { className: "multipleradio-overlay", children: _jsxs("div", { className: "multipleradio-box", style: (state === null || state === void 0 ? void 0 : state.style) !== undefined ? state.style : {}, role: "dialog", "aria-modal": "true", "aria-labelledby": (state === null || state === void 0 ? void 0 : state.headline) != null ? "multiple-radio-headline" : undefined, "aria-label": (state === null || state === void 0 ? void 0 : state.headline) != null ? undefined : "Einfachauswahl", "aria-describedby": "multiple-radio-message", onKeyDown: (event) => { if (event.key === "Escape")
65
+ handleAction(state.handlerCancel, false); }, children: [state.addCloseButton ?
66
66
  _jsx("span", { className: "closeButton", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", tabIndex: 0, className: "close-icon", onClick: () => handleAction(undefined, false), onKeyDown: (e) => {
67
67
  if (e.key === 'Enter' || e.key === ' ') {
68
68
  e.preventDefault(); // Verhindert Scroll bei Space
69
69
  handleAction(undefined, false);
70
70
  }
71
71
  }, role: "button", "aria-label": "Dialog schlie\u00DFen", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) }) :
72
- _jsx(_Fragment, {}), _jsx("div", { className: "headline", id: "theHeadline", tabIndex: 0, style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) != null ? state.headline : "" }) }), _jsx("div", { tabIndex: 0, style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) != null ? state.message : "" }), _jsx("div", { className: "radios-input", children: _jsx("div", { className: "radios-container", children: state === null || state === void 0 ? void 0 : state.choices.map(choice => {
72
+ _jsx(_Fragment, {}), _jsx("div", { className: "headline", id: "multiple-radio-headline", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: _jsx("strong", { children: (state === null || state === void 0 ? void 0 : state.headline) != null ? state.headline : "" }) }), _jsx("div", { id: "multiple-radio-message", style: { whiteSpace: "pre-line", wordBreak: "break-word" }, children: (state === null || state === void 0 ? void 0 : state.message) != null ? state.message : "" }), _jsx("div", { className: "radios-input", role: "radiogroup", "aria-label": "Auswahloptionen", children: _jsx("div", { className: "radios-container", children: state === null || state === void 0 ? void 0 : state.choices.map(choice => {
73
73
  var _a;
74
- return (_jsxs("label", { className: "radio-label", children: [_jsx("input", { type: "radio", checked: input === choice, disabled: (_a = state.disabledChoices) === null || _a === void 0 ? void 0 : _a.includes(choice), onChange: () => setInput(choice), tabIndex: 0, onKeyDown: (e) => {
74
+ return (_jsxs("label", { className: "radio-label", children: [_jsx("input", { type: "radio", name: "multiple-radio-options", checked: input === choice, disabled: (_a = state.disabledChoices) === null || _a === void 0 ? void 0 : _a.includes(choice), onChange: () => setInput(choice), tabIndex: 0, onKeyDown: (e) => {
75
75
  if (e.key === 'Enter' || e.key === ' ') {
76
76
  e.preventDefault(); // Verhindert Scroll bei Space
77
77
  setInput(choice);
@@ -82,7 +82,7 @@ export function MultipleRadioOverlay({ state, setState }) {
82
82
  event.preventDefault(); // Verhindert Scroll bei Space
83
83
  handleAction(state.handlerCancel, false);
84
84
  }
85
- }, className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) != null ? state.cancelButtonStyle : {}, children: (state === null || state === void 0 ? void 0 : state.cancelButtonText) != null ? state.cancelButtonText : "Abbrechen" }), _jsx("button", { onClick: () => handleAction(state.handlerOk, true), id: "confirmButton", onKeyDown: (event) => {
85
+ }, className: "px-4 py-2 bg-gray-300 rounded", style: (state === null || state === void 0 ? void 0 : state.cancelButtonStyle) != null ? state.cancelButtonStyle : {}, children: (state === null || state === void 0 ? void 0 : state.cancelButtonText) != null ? state.cancelButtonText : "Abbrechen" }), _jsx("button", { onClick: () => handleAction(state.handlerOk, true), type: "button", autoFocus: true, onKeyDown: (event) => {
86
86
  if (event.key === "Enter" || event.key === ' ') {
87
87
  event.preventDefault(); // Verhindert Scroll bei Space
88
88
  handleAction(state.handlerOk, true);
package/dist/Toast.js CHANGED
@@ -19,5 +19,5 @@ export function Toast({ state, setState }) {
19
19
  setShowToast(false);
20
20
  }
21
21
  }, [toastContent, setState]);
22
- return _jsx(_Fragment, { children: showToast && (_jsx("div", { className: "toast-notification", children: toastContent })) });
22
+ return _jsx(_Fragment, { children: showToast && (_jsx("div", { className: "toast-notification", role: "status", "aria-live": "polite", "aria-atomic": "true", children: toastContent })) });
23
23
  }
@@ -14,6 +14,9 @@
14
14
  }
15
15
 
16
16
  .toggleOption {
17
+ border: 0;
18
+ background: transparent;
19
+ font: inherit;
17
20
  flex: 1;
18
21
  display: flex;
19
22
  justify-content: center;
@@ -25,6 +28,11 @@
25
28
  white-space: nowrap;
26
29
  }
27
30
 
31
+ .toggleOption:focus-visible {
32
+ outline: 3px solid var(--DunkelAkzent, #8b0000);
33
+ outline-offset: -3px;
34
+ }
35
+
28
36
  .toggleOption.active {
29
37
  color: black;
30
38
  }
@@ -23,5 +23,5 @@ export function ToggleSwitch({ optionLeft, optionRight, value, onChange }) {
23
23
  width: `calc(${offsetWidth}px + 2rem)`
24
24
  });
25
25
  }, [value, optionLeft, optionRight]);
26
- return (_jsxs("div", { className: "toggleWrapper", ref: containerRef, children: [_jsx("div", { className: `toggleOption ${value === optionLeft.value ? "active" : ""}`, ref: el => { optionLeftRef.current = el; }, onClick: () => onChange(optionLeft.value), children: optionLeft.label }), _jsx("div", { className: `toggleOption ${value === optionRight.value ? "active" : ""}`, ref: el => { optionRightRef.current = el; }, onClick: () => onChange(optionRight.value), children: optionRight.label }), _jsx("div", { className: `toggleSlider ${value === optionLeft.value ? "left" : "right"}`, style: sliderStyle })] }));
26
+ return (_jsxs("div", { className: "toggleWrapper", ref: containerRef, role: "group", "aria-label": "Auswahl", children: [_jsx("button", { type: "button", className: `toggleOption ${value === optionLeft.value ? "active" : ""}`, ref: el => { optionLeftRef.current = el; }, onClick: () => onChange(optionLeft.value), "aria-pressed": value === optionLeft.value, children: optionLeft.label }), _jsx("button", { type: "button", className: `toggleOption ${value === optionRight.value ? "active" : ""}`, ref: el => { optionRightRef.current = el; }, onClick: () => onChange(optionRight.value), "aria-pressed": value === optionRight.value, children: optionRight.label }), _jsx("div", { className: `toggleSlider ${value === optionLeft.value ? "left" : "right"}`, style: sliderStyle, "aria-hidden": "true" })] }));
27
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typescript-overlay-essentials",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Eine kleine Ansammlung an praktischen Tools, die out of the Box genutzt werden können. Alle enthaltenen Overlays können als Reaktion auf etwas geöffnet werden und schließen sich danach automatisch. Es beinhaltet: \\n - [ConfirmationBox]: Ein Overlay mit einer ConfirmationBox (Fortfahren / Abbrechen), \\n - [InfoOverlay]: ein simples Overlay mit einer Informationsbox die man bestätigen kann, \\n - [InfoOverlayWithInput]: Ein Overlay bei dem ein User zusätzlich ein Freitext-Feld zur Eingabe hat, \\n - [LoadingOverlay]: Ein simples Overlay mit einer Lade-animation und optionalem Ladetext, \\n - [MultipleChoiceOverlay]: Ein simples Overlay bei dem ein Nutzer aus mehreren gegebenen Aktionen auswählen kann, \\n - [MultipleRadioOverlay]: Ein simples Overlay bei dem ein Nutzer genau eine aus mehreren gegebenen Aktionen auswählen kann, \\n - [Toast]: Ein simpler Toast der für kurze Zeit grün hinterlegt in der oberen rechten Ecke des Bildschirms angezeigt wird, \\n - [ToggleSwitch]: Eine Auswahl aus zwei Optionen aus denen ein Nutzer wählen kann in der Darstellung (Option 1 | Option 2), \\n - [Dropdown]: Ein simples Dropdown-Menü (auf Basis von react-select), welches einfacherer zu Konfigurieren ist und einige default-Einstellungen hat, \\n - [InputFilter]: Ein Tool was genutzt werden kann um auf einem Inputfeld einen Regex-Filter anzuwenden und dem User so nur Eingaben erlaubt die dem Filter entsprechen.",
5
5
  "keywords": [
6
6
  "typescript",