@inera/ids-react 7.0.1 → 7.1.1
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/components/accordion/accordion.d.ts +1 -0
- package/components/accordion/accordion.js +2 -1
- package/components/dialog/dialog.js +1 -0
- package/components/form/check-button/check-button.d.ts +1 -0
- package/components/form/check-button/check-button.js +4 -2
- package/components/form/checkbox/checkbox-group.d.ts +1 -0
- package/components/form/checkbox/checkbox-group.js +17 -28
- package/components/form/checkbox/checkbox.d.ts +1 -0
- package/components/form/checkbox/checkbox.js +4 -2
- package/components/form/form-hooks/useGroupValidity.d.ts +1 -1
- package/components/form/form-hooks/useGroupValidity.js +5 -4
- package/components/form/input/input.d.ts +1 -0
- package/components/form/input/input.js +4 -5
- package/components/form/radio/radio.d.ts +1 -0
- package/components/form/radio/radio.js +4 -3
- package/components/form/radio-button/radio-button.d.ts +1 -0
- package/components/form/radio-button/radio-button.js +4 -2
- package/components/form/range/range.d.ts +1 -0
- package/components/form/range/range.js +4 -2
- package/components/form/select/select.d.ts +1 -0
- package/components/form/select/select.js +3 -2
- package/components/form/select-multiple/select-multiple.d.ts +1 -0
- package/components/form/select-multiple/select-multiple.js +7 -3
- package/components/form/textarea/textarea.d.ts +1 -0
- package/components/form/textarea/textarea.js +3 -2
- package/components/form/time/time.d.ts +1 -0
- package/components/form/time/time.js +3 -2
- package/components/form/toggle/toggle.d.ts +1 -0
- package/components/form/toggle/toggle.js +4 -2
- package/components/header-1177/header-1177-avatar.js +24 -11
- package/components/header-1177/header-1177-nav-item.js +22 -5
- package/components/header-1177-admin/header-1177-admin-nav-item.js +21 -6
- package/components/header-1177-pro/header-1177-pro-nav-item.js +21 -6
- package/components/header-inera/header-inera-nav-item.js +6 -1
- package/components/header-inera-admin/header-inera-admin-nav-item.js +6 -1
- package/components/link/link.d.ts +3 -3
- package/components/puff-list/puff-list-item/puff-list-item.d.ts +1 -0
- package/components/puff-list/puff-list-item/puff-list-item.js +9 -7
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@ import clsx from 'clsx';
|
|
|
5
5
|
import '@inera/ids-design/components/accordion/accordion.css';
|
|
6
6
|
import { useElementId } from '../utils/hooks/useElementId.js';
|
|
7
7
|
|
|
8
|
-
const IDSAccordion = ({ headline = "", level = 1, headlineSize = level === 2 ? "s" : "m", expanded = false, lean = false, onCollapsed, onExpanded, children, className, ...props }) => {
|
|
8
|
+
const IDSAccordion = ({ headline = "", level = 1, headlineSize = level === 2 ? "s" : "m", expanded = false, lean = false, noBorder = false, onCollapsed, onExpanded, children, className, ...props }) => {
|
|
9
9
|
const [isExpanded, setIsExpanded] = useState(expanded);
|
|
10
10
|
const [isLean, setIsLean] = useState(lean);
|
|
11
11
|
const [insideIDSCard, setInsideIDSCard] = useState(false);
|
|
@@ -63,6 +63,7 @@ const IDSAccordion = ({ headline = "", level = 1, headlineSize = level === 2 ? "
|
|
|
63
63
|
};
|
|
64
64
|
return (jsxs("div", { ref: accordionRef, className: clsx("ids-accordion", {
|
|
65
65
|
"ids-accordion--expanded": isExpanded,
|
|
66
|
+
"ids-accordion--no-border": noBorder,
|
|
66
67
|
"ids-accordion--lean": lean || isLean,
|
|
67
68
|
"ids-accordion--has-children": hasChildren,
|
|
68
69
|
"ids-accordion--is-child": level === 2
|
|
@@ -51,6 +51,7 @@ const IDSDialog = ({ show = false, srClose = "Stäng", dismissible = false, auto
|
|
|
51
51
|
const focusable = bodyRef.current?.querySelector(".ids-focus-anchor") ||
|
|
52
52
|
bodyRef.current?.querySelector("h1, h2, h3, [tabindex]:not([tabindex='-1']), button:not([disabled]), a, input:not([disabled]), textarea:not([disabled])") ||
|
|
53
53
|
dialogRef.current?.querySelector("button.ids-dialog__header__button");
|
|
54
|
+
console.log("focusable", focusable);
|
|
54
55
|
focusable?.focus();
|
|
55
56
|
});
|
|
56
57
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode, InputHTMLAttributes } from "react";
|
|
2
2
|
interface IDSCheckButtonProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
3
3
|
disabled?: boolean;
|
|
4
|
+
focusAnchor?: boolean;
|
|
4
5
|
children?: ReactNode;
|
|
5
6
|
}
|
|
6
7
|
export declare const IDSCheckButton: import("react").ForwardRefExoticComponent<IDSCheckButtonProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -4,11 +4,13 @@ import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
|
|
7
|
-
const IDSCheckButton = forwardRef(({ disabled = false, id, children, className, ...props }, ref) => {
|
|
7
|
+
const IDSCheckButton = forwardRef(({ disabled = false, focusAnchor = false, id, children, className, ...props }, ref) => {
|
|
8
8
|
const fieldId = useElementId(id);
|
|
9
9
|
const checkButtonRef = useRef(null);
|
|
10
10
|
useImperativeHandle(ref, () => checkButtonRef.current);
|
|
11
|
-
return (jsxs("div", { className: clsx("ids-check-button", { "ids-check-button--disabled": disabled }, className), children: [jsx("input", { id: fieldId, ref: checkButtonRef, className: "ids-check-button__input",
|
|
11
|
+
return (jsxs("div", { className: clsx("ids-check-button", { "ids-check-button--disabled": disabled }, className), children: [jsx("input", { id: fieldId, ref: checkButtonRef, className: clsx("ids-check-button__input", {
|
|
12
|
+
"ids-focus-anchor": focusAnchor
|
|
13
|
+
}), type: "checkbox", disabled: disabled, ...props }), jsx("label", { htmlFor: fieldId, className: "ids-check-button__label", children: children })] }));
|
|
12
14
|
});
|
|
13
15
|
IDSCheckButton.displayName = "IDSCheckButton";
|
|
14
16
|
|
|
@@ -5,6 +5,7 @@ interface IDSCheckboxGroupProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
|
5
5
|
compact?: boolean;
|
|
6
6
|
tooltip?: ReactNode;
|
|
7
7
|
block?: boolean;
|
|
8
|
+
noValidation?: boolean;
|
|
8
9
|
children?: ReactNode;
|
|
9
10
|
onValidityChange?: (isValid: boolean) => void;
|
|
10
11
|
setCheckedBoxesCount?: Dispatch<SetStateAction<number>>;
|
|
@@ -6,42 +6,31 @@ import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
|
6
6
|
import { useGroupValidity } from '../form-hooks/useGroupValidity.js';
|
|
7
7
|
import clsx from 'clsx';
|
|
8
8
|
|
|
9
|
-
const IDSCheckboxGroup = ({ legend = "", errorMsg = "", compact = false, block = false, tooltip, children, className, onValidityChange, setCheckedBoxesCount }) => {
|
|
9
|
+
const IDSCheckboxGroup = ({ legend = "", errorMsg = "", compact = false, block = false, noValidation = false, tooltip, children, className, onValidityChange, setCheckedBoxesCount }) => {
|
|
10
10
|
const groupRef = useRef(null);
|
|
11
|
-
const isValid = useGroupValidity(groupRef, "checkbox")
|
|
11
|
+
const isValid = useGroupValidity(groupRef, "checkbox", () => {
|
|
12
|
+
onValidityChange?.(false);
|
|
13
|
+
});
|
|
12
14
|
const errorMsgId = useElementId();
|
|
13
15
|
useEffect(() => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
}, [isValid, onValidityChange]);
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
const checkboxes = groupRef.current?.querySelectorAll(`input[type="checkbox"]`);
|
|
20
|
-
if (!checkboxes.length)
|
|
21
|
-
return;
|
|
22
|
-
const count = () => {
|
|
23
|
-
const checkedCount = groupRef.current?.querySelectorAll('input[type="checkbox"]:checked')?.length ?? 0;
|
|
24
|
-
if (setCheckedBoxesCount) {
|
|
25
|
-
setCheckedBoxesCount(checkedCount);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
count();
|
|
29
|
-
checkboxes.forEach(cb => {
|
|
30
|
-
cb.addEventListener("change", count);
|
|
31
|
-
});
|
|
32
|
-
return () => {
|
|
33
|
-
checkboxes.forEach(cb => {
|
|
34
|
-
cb.removeEventListener("change", count);
|
|
35
|
-
});
|
|
36
|
-
};
|
|
16
|
+
const checkedCount = groupRef.current?.querySelectorAll('input[type="checkbox"]:checked')?.length ?? 0;
|
|
17
|
+
setCheckedBoxesCount?.(checkedCount);
|
|
37
18
|
}, [groupRef]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
onValidityChange?.(isValid);
|
|
21
|
+
}, [isValid, onValidityChange]);
|
|
38
22
|
const clonedChildren = React__default.Children.map(children, child => {
|
|
39
|
-
if (React__default.isValidElement(child) &&
|
|
40
|
-
child.type.displayName === "IDSCheckbox") {
|
|
23
|
+
if (React__default.isValidElement(child) && child.type.displayName === "IDSCheckbox") {
|
|
41
24
|
return React__default.cloneElement(child, {
|
|
42
25
|
key: child.props.id,
|
|
43
26
|
groupErrorMsgId: errorMsg && errorMsgId,
|
|
44
|
-
block: block
|
|
27
|
+
block: block,
|
|
28
|
+
noValidation: noValidation,
|
|
29
|
+
onChange: (e) => {
|
|
30
|
+
child.props.onChange?.(e);
|
|
31
|
+
const checkedCount = groupRef.current?.querySelectorAll('input[type="checkbox"]:checked')?.length ?? 0;
|
|
32
|
+
setCheckedBoxesCount?.(checkedCount);
|
|
33
|
+
}
|
|
45
34
|
});
|
|
46
35
|
}
|
|
47
36
|
return child;
|
|
@@ -7,7 +7,7 @@ import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
|
7
7
|
import { useInputValidity } from '../form-hooks/useInputValidity.js';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
|
|
10
|
-
const IDSCheckbox = forwardRef(({ invalid = false, disabled = false, required = false, indeterminate = false, noValidation = false, noLabel = false, light = false, block = false, compact = false, errorMsg = "", groupErrorMsgId = "", tooltip, id, children, className, ...props }, ref) => {
|
|
10
|
+
const IDSCheckbox = forwardRef(({ invalid = false, disabled = false, required = false, indeterminate = false, noValidation = false, noLabel = false, light = false, block = false, compact = false, focusAnchor = false, errorMsg = "", groupErrorMsgId = "", tooltip, id, children, className, ...props }, ref) => {
|
|
11
11
|
const internalRef = useRef(null);
|
|
12
12
|
const checkboxRef = ref ?? internalRef;
|
|
13
13
|
const fieldId = useElementId(id);
|
|
@@ -42,7 +42,9 @@ const IDSCheckbox = forwardRef(({ invalid = false, disabled = false, required =
|
|
|
42
42
|
"ids-checkbox--light": light,
|
|
43
43
|
"ids-checkbox--block": block,
|
|
44
44
|
"ids-checkbox--compact": compact
|
|
45
|
-
}), children: [jsx("input", { id: fieldId, ref: checkboxRef, type: "checkbox", className:
|
|
45
|
+
}), children: [jsx("input", { id: fieldId, ref: checkboxRef, type: "checkbox", className: clsx("ids-checkbox__input", {
|
|
46
|
+
"ids-focus-anchor": focusAnchor
|
|
47
|
+
}), "aria-invalid": isInvalid, disabled: disabled, "aria-disabled": disabled, required: !noValidation && required, "aria-required": !noValidation && required, ...props }), jsxs("div", { className: clsx("ids-label-tooltip-wrapper", {
|
|
46
48
|
"ids-label-tooltip-wrapper--block": block,
|
|
47
49
|
"ids-label-tooltip-wrapper--inline": tooltip
|
|
48
50
|
}), children: [jsx("label", { htmlFor: fieldId, className: clsx("ds-checkbox__label", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function useGroupValidity(ref: React.RefObject<HTMLFieldSetElement>, type: "checkbox" | "radio"): boolean;
|
|
1
|
+
export declare function useGroupValidity(ref: React.RefObject<HTMLFieldSetElement>, type: "checkbox" | "radio", onInvalid?: () => void): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState, useRef, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
function useGroupValidity(ref, type) {
|
|
3
|
+
function useGroupValidity(ref, type, onInvalid) {
|
|
4
4
|
const [isValid, setIsValid] = useState(true);
|
|
5
5
|
const [hasInteracted, setHasInteracted] = useState(false);
|
|
6
6
|
const initialized = useRef(false);
|
|
@@ -29,6 +29,7 @@ function useGroupValidity(ref, type) {
|
|
|
29
29
|
initialized.current = true;
|
|
30
30
|
}
|
|
31
31
|
const handleInteraction = () => {
|
|
32
|
+
onInvalid?.();
|
|
32
33
|
setHasInteracted(true);
|
|
33
34
|
validate();
|
|
34
35
|
};
|
|
@@ -38,7 +39,7 @@ function useGroupValidity(ref, type) {
|
|
|
38
39
|
};
|
|
39
40
|
inputs.forEach(cb => {
|
|
40
41
|
cb.addEventListener("invalid", handleInteraction);
|
|
41
|
-
cb.addEventListener("
|
|
42
|
+
cb.addEventListener("input", handleChange);
|
|
42
43
|
});
|
|
43
44
|
const form = fieldset.closest("form");
|
|
44
45
|
const handleSubmit = () => {
|
|
@@ -49,11 +50,11 @@ function useGroupValidity(ref, type) {
|
|
|
49
50
|
return () => {
|
|
50
51
|
inputs.forEach(cb => {
|
|
51
52
|
cb.removeEventListener("invalid", handleInteraction);
|
|
52
|
-
cb.removeEventListener("
|
|
53
|
+
cb.removeEventListener("input", handleChange);
|
|
53
54
|
});
|
|
54
55
|
form?.removeEventListener("submit", handleSubmit);
|
|
55
56
|
};
|
|
56
|
-
}, [ref]);
|
|
57
|
+
}, [ref, onInvalid]);
|
|
57
58
|
return isValid || !hasInteracted;
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -7,7 +7,7 @@ import { useInputValidity } from '../form-hooks/useInputValidity.js';
|
|
|
7
7
|
import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
|
|
10
|
-
const IDSInput = forwardRef(({ label = "", type = "text", icon = "", hint = "", showSearchLabel = false, errorMsg = "", disabled = false, invalid = false, required = false, noValidation = false, autoSize = false, block = false, light = false, readOnly = false, id, tooltip, submitButton, oldIcon, className, ...props }, ref) => {
|
|
10
|
+
const IDSInput = forwardRef(({ label = "", type = "text", icon = "", hint = "", showSearchLabel = false, errorMsg = "", disabled = false, invalid = false, required = false, noValidation = false, autoSize = false, block = false, light = false, readOnly = false, focusAnchor = false, id, tooltip, submitButton, oldIcon, className, ...props }, ref) => {
|
|
11
11
|
const fieldId = useElementId(id);
|
|
12
12
|
const errorMsgId = useElementId();
|
|
13
13
|
const hintId = useElementId();
|
|
@@ -43,9 +43,7 @@ const IDSInput = forwardRef(({ label = "", type = "text", icon = "", hint = "",
|
|
|
43
43
|
iconComponent.setAttribute("color", color);
|
|
44
44
|
iconComponent.setAttribute("color2", color2);
|
|
45
45
|
};
|
|
46
|
-
const renderOldIcon = oldIcon && React__default.isValidElement(oldIcon)
|
|
47
|
-
? React__default.cloneElement(oldIcon, { ref: oldIconRef })
|
|
48
|
-
: oldIcon;
|
|
46
|
+
const renderOldIcon = oldIcon && React__default.isValidElement(oldIcon) ? React__default.cloneElement(oldIcon, { ref: oldIconRef }) : oldIcon;
|
|
49
47
|
return (jsxs("div", { className: clsx("ids-input-component", className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { className: clsx("ids-label", {
|
|
50
48
|
"ids-label--disabled": disabled || readOnly,
|
|
51
49
|
"ids-hidden": type === "search" && !showSearchLabel
|
|
@@ -54,7 +52,8 @@ const IDSInput = forwardRef(({ label = "", type = "text", icon = "", hint = "",
|
|
|
54
52
|
"ids-input__inner-wrapper--search": type === "search"
|
|
55
53
|
}), children: [jsx("input", { ref: combinedRef, id: fieldId, type: type, readOnly: readOnly, className: clsx("ids-input", {
|
|
56
54
|
"ids-input--light": light,
|
|
57
|
-
"ids-input--invalid": invalid
|
|
55
|
+
"ids-input--invalid": invalid,
|
|
56
|
+
"ids-focus-anchor": focusAnchor
|
|
58
57
|
}), "aria-invalid": isInvalid, required: required, "aria-required": required, disabled: disabled, "aria-disabled": disabled, ...props }), type === "search" && jsx("span", { className: "ids-input__search-icon" }), icon && jsx("span", { className: `ids-input__icon ids-icon-${icon}` }), oldIcon && jsx("span", { className: "ids-input__icon", children: renderOldIcon })] }), submitButton] }), hint && (jsx("div", { id: hintId, className: "ids-input__hint", children: hint })), isInvalid && errorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, children: errorMsg }))] }));
|
|
59
58
|
});
|
|
60
59
|
IDSInput.displayName = "IDSInput"; // Needed when using forwardRef
|
|
@@ -10,6 +10,7 @@ export interface IDSRadioProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
|
10
10
|
noValidation?: boolean;
|
|
11
11
|
light?: boolean;
|
|
12
12
|
compact?: boolean;
|
|
13
|
+
focusAnchor?: boolean;
|
|
13
14
|
tooltip?: ReactNode;
|
|
14
15
|
children?: ReactNode;
|
|
15
16
|
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
@@ -6,7 +6,7 @@ import { useInputValidity } from '../form-hooks/useInputValidity.js';
|
|
|
6
6
|
import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
7
7
|
import clsx from 'clsx';
|
|
8
8
|
|
|
9
|
-
const IDSRadio = forwardRef(({ name = "", groupErrorMsgId = "", invalid = false, groupInvalid = false, disabled = false, noValidation = false, light = false, compact = false, tooltip, id, children, className, onChange, ...props }, ref) => {
|
|
9
|
+
const IDSRadio = forwardRef(({ name = "", groupErrorMsgId = "", invalid = false, groupInvalid = false, disabled = false, noValidation = false, light = false, compact = false, focusAnchor = false, tooltip, id, children, className, onChange, ...props }, ref) => {
|
|
10
10
|
const fieldId = useElementId(id);
|
|
11
11
|
const radioRef = useRef(null);
|
|
12
12
|
useImperativeHandle(ref, () => radioRef.current);
|
|
@@ -15,8 +15,9 @@ const IDSRadio = forwardRef(({ name = "", groupErrorMsgId = "", invalid = false,
|
|
|
15
15
|
useAriaDescribedBy(radioRef, groupErrorMsgId, isInvalid, !!groupErrorMsgId);
|
|
16
16
|
return (jsxs("div", { className: clsx("ids-radio", {
|
|
17
17
|
"ids-radio--compact": compact
|
|
18
|
-
}, className), children: [jsx("input", { id: fieldId, ref: radioRef, type: "radio", className: clsx({
|
|
19
|
-
"ids-input--light": light
|
|
18
|
+
}, className), children: [jsx("input", { id: fieldId, ref: radioRef, type: "radio", className: clsx("ids-radio__input", {
|
|
19
|
+
"ids-input--light": light,
|
|
20
|
+
"ids-focus-anchor": focusAnchor
|
|
20
21
|
}), disabled: disabled, "aria-disabled": disabled, "aria-invalid": isInvalid, name: name, onChange: onChange, ...props }), jsxs("div", { className: clsx("ids-label-tooltip-wrapper", {
|
|
21
22
|
"ids-label-tooltip-wrapper--inline": tooltip
|
|
22
23
|
}), children: [jsx("label", { htmlFor: fieldId, className: clsx("ids-radio__label ids-label", {
|
|
@@ -2,6 +2,7 @@ import React, { ReactNode, InputHTMLAttributes } from "react";
|
|
|
2
2
|
export interface IDSRadioButtonProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
3
3
|
name?: string;
|
|
4
4
|
id?: string;
|
|
5
|
+
focusAnchor?: boolean;
|
|
5
6
|
icon: string;
|
|
6
7
|
children?: ReactNode;
|
|
7
8
|
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
@@ -4,11 +4,13 @@ import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
|
|
7
|
-
const IDSRadioButton = forwardRef(({ name = "", icon = "user", id, children, onChange, className, ...props }, ref) => {
|
|
7
|
+
const IDSRadioButton = forwardRef(({ name = "", icon = "user", focusAnchor = false, id, children, onChange, className, ...props }, ref) => {
|
|
8
8
|
const fieldId = useElementId(id);
|
|
9
9
|
const radioButtonRef = useRef(null);
|
|
10
10
|
useImperativeHandle(ref, () => radioButtonRef.current);
|
|
11
|
-
return (jsxs("div", { className: clsx("ids-radio-button", className), children: [jsx("input", { id: fieldId, ref: radioButtonRef, type: "radio", className: "ids-radio-button__input",
|
|
11
|
+
return (jsxs("div", { className: clsx("ids-radio-button", className), children: [jsx("input", { id: fieldId, ref: radioButtonRef, type: "radio", className: clsx("ids-radio-button__input", {
|
|
12
|
+
"ids-focus-anchor": focusAnchor
|
|
13
|
+
}), name: name, onChange: onChange, ...props }), jsx("label", { htmlFor: fieldId, className: `ids-radio-button__label ids-icon-${icon}`, children: children })] }));
|
|
12
14
|
});
|
|
13
15
|
IDSRadioButton.displayName = "IDSRadioButton";
|
|
14
16
|
|
|
@@ -5,7 +5,7 @@ import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
|
5
5
|
import '@inera/ids-design/components/form/range/range.css';
|
|
6
6
|
import clsx from 'clsx';
|
|
7
7
|
|
|
8
|
-
const IDSRange = forwardRef(({ label = "", value = 0, showTicks = false, interval = 0, min = 0, max = 0, step = 0, disabled = false, tooltip, id, onChange, className, ...props }, ref) => {
|
|
8
|
+
const IDSRange = forwardRef(({ label = "", value = 0, showTicks = false, interval = 0, min = 0, max = 0, step = 0, disabled = false, focusAnchor = false, tooltip, id, onChange, className, ...props }, ref) => {
|
|
9
9
|
const [internalValue, setInternalValue] = useState(value);
|
|
10
10
|
const [ticks, setTicks] = useState([]);
|
|
11
11
|
const fieldId = useElementId(id);
|
|
@@ -27,7 +27,9 @@ const IDSRange = forwardRef(({ label = "", value = 0, showTicks = false, interva
|
|
|
27
27
|
onChange(ev);
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
-
return (jsxs("div", { className: clsx("ids-range", className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { htmlFor: fieldId, className: clsx("ids-label", { "ids-label--disabled": disabled }), children: label }), tooltip] }), jsx("input", { id: fieldId, ref: rangeRef, type: "range", className:
|
|
30
|
+
return (jsxs("div", { className: clsx("ids-range", className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { htmlFor: fieldId, className: clsx("ids-label", { "ids-label--disabled": disabled }), children: label }), tooltip] }), jsx("input", { id: fieldId, ref: rangeRef, type: "range", className: clsx("ids-range__input", {
|
|
31
|
+
"ids-focus-anchor": focusAnchor
|
|
32
|
+
}), min: min, "aria-valuemin": min, max: max, "aria-valuemax": max, step: step, value: internalValue, "aria-valuenow": internalValue, disabled: disabled, style: { backgroundSize: ((internalValue - min) * 100) / (max - min) + "% 100%" }, onChange: handleOnChange, ...props }), showTicks && (jsx("div", { className: clsx("ids-range-ticks", { "ids-range-ticks--disabled": disabled }), children: ticks.map(tick => (jsx("div", { className: "ids-range-tick", children: tick }, tick))) }))] }));
|
|
31
33
|
});
|
|
32
34
|
IDSRange.displayName = "IDSRange";
|
|
33
35
|
|
|
@@ -7,7 +7,7 @@ import { useInputValidity } from '../form-hooks/useInputValidity.js';
|
|
|
7
7
|
import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
|
|
10
|
-
const IDSSelect = forwardRef(({ label = "", srOf = "av", errorMsg = "", disabled = false, required = false, invalid = false, light = false, noValidation = false, tooltip, id, children, className, ...props }, ref) => {
|
|
10
|
+
const IDSSelect = forwardRef(({ label = "", srOf = "av", errorMsg = "", disabled = false, required = false, invalid = false, light = false, noValidation = false, focusAnchor = false, tooltip, id, children, className, ...props }, ref) => {
|
|
11
11
|
const fieldId = useElementId(id);
|
|
12
12
|
const errorMsgId = useElementId();
|
|
13
13
|
const selectRef = useRef(null);
|
|
@@ -16,7 +16,8 @@ const IDSSelect = forwardRef(({ label = "", srOf = "av", errorMsg = "", disabled
|
|
|
16
16
|
const isInvalid = (invalid || !hasValidValue) && !noValidation;
|
|
17
17
|
useAriaDescribedBy(selectRef, errorMsgId, isInvalid, !!errorMsg);
|
|
18
18
|
return (jsxs("div", { className: clsx("ids-select-component", className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { htmlFor: fieldId, className: "ids-label", children: label }), tooltip] }), jsx("div", { className: "ids-select-wrapper", children: jsx("select", { id: fieldId, ref: selectRef, className: clsx("ids-select", {
|
|
19
|
-
"ids-input--light": light
|
|
19
|
+
"ids-input--light": light,
|
|
20
|
+
"ids-focus-anchor": focusAnchor
|
|
20
21
|
}), "aria-invalid": isInvalid, required: required, disabled: disabled, ...props, children: children }) }), isInvalid && errorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, children: errorMsg }))] }));
|
|
21
22
|
});
|
|
22
23
|
IDSSelect.displayName = "IDSSelect";
|
|
@@ -7,7 +7,7 @@ import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
|
7
7
|
import '@inera/ids-design/components/form/select-multiple/select-multiple.css';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
|
|
10
|
-
const IDSSelectMultiple = ({ label = "", selectedLabel = "vald", selectedLabelPlural = "valda", placeholder = "", maxHeight = "", expanded = false, errorMsg = "", invalid = false, light = false, noValidation = false, tooltip, id, children, className, ...props }) => {
|
|
10
|
+
const IDSSelectMultiple = ({ label = "", selectedLabel = "vald", selectedLabelPlural = "valda", placeholder = "", maxHeight = "", expanded = false, errorMsg = "", invalid = false, light = false, noValidation = false, focusAnchor = false, tooltip, id, children, className, ...props }) => {
|
|
11
11
|
const [checkboxListInvalid, setCheckboxListInvalid] = useState(false);
|
|
12
12
|
const [checkedBoxesCount, setCheckedBoxesCount] = useState(0);
|
|
13
13
|
const [value, setValue] = useState(placeholder);
|
|
@@ -52,10 +52,14 @@ const IDSSelectMultiple = ({ label = "", selectedLabel = "vald", selectedLabelPl
|
|
|
52
52
|
};
|
|
53
53
|
}, [isExpanded]);
|
|
54
54
|
return (jsxs("div", { className: clsx("ids-select-multiple-component", className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { id: labelId, htmlFor: inputId, className: "ids-label", children: label }), tooltip] }), jsx("div", { className: "ids-select-multiple-wrapper", children: jsx("input", { id: inputId, "aria-labelledby": labelId, ref: selectMultipleRef, type: "button", className: clsx("ids-select-multiple__select", {
|
|
55
|
-
"ids-input--light": light
|
|
55
|
+
"ids-input--light": light,
|
|
56
|
+
"ids-focus-anchor": focusAnchor
|
|
56
57
|
}), "aria-expanded": isExpanded, "aria-invalid": invalid || checkboxListInvalid, placeholder: placeholder, value: value, onClick: () => setIsExpanded(!isExpanded), ...props }) }), jsx("div", { className: "ids-select-multiple__dropdown__wrapper", children: jsx("div", { className: clsx("ids-select-multiple__dropdown", {
|
|
57
58
|
"ids-select-multiple__dropdown--show": isExpanded
|
|
58
|
-
}), children: jsx("div", { className: "ids-select-multiple__dropdown__inner", style: { maxHeight: maxHeight }, children: jsx(IDSCheckboxGroup, { block: true, errorMsg: errorMsg, setCheckedBoxesCount: setCheckedBoxesCount, onValidityChange: (isValid) => {
|
|
59
|
+
}), children: jsx("div", { className: "ids-select-multiple__dropdown__inner", style: { maxHeight: maxHeight }, children: jsx(IDSCheckboxGroup, { block: true, noValidation: noValidation, errorMsg: errorMsg, setCheckedBoxesCount: setCheckedBoxesCount, onValidityChange: (isValid) => {
|
|
60
|
+
if (!isValid) {
|
|
61
|
+
setIsExpanded(true);
|
|
62
|
+
}
|
|
59
63
|
setCheckboxListInvalid(!isValid);
|
|
60
64
|
}, children: children }) }) }) })] }));
|
|
61
65
|
};
|
|
@@ -7,7 +7,7 @@ import { useInputValidity } from '../form-hooks/useInputValidity.js';
|
|
|
7
7
|
import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
|
|
10
|
-
const IDSTextarea = forwardRef(({ label = "", hint, errorMsg = "", disabled = false, invalid = false, required = false, noValidation = false, autoSize = false, noResize = false, block = false, light = false, readOnly = false, id, tooltip, className, ...props }, ref) => {
|
|
10
|
+
const IDSTextarea = forwardRef(({ label = "", hint, errorMsg = "", disabled = false, invalid = false, required = false, noValidation = false, autoSize = false, noResize = false, block = false, light = false, readOnly = false, focusAnchor = false, id, tooltip, className, ...props }, ref) => {
|
|
11
11
|
const fieldId = useElementId(id);
|
|
12
12
|
const errorMsgId = useElementId();
|
|
13
13
|
const hintId = useElementId();
|
|
@@ -23,7 +23,8 @@ const IDSTextarea = forwardRef(({ label = "", hint, errorMsg = "", disabled = fa
|
|
|
23
23
|
}, className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { className: clsx("ids-label", {
|
|
24
24
|
"ids-label--disabled": disabled || readOnly
|
|
25
25
|
}), htmlFor: fieldId, children: label }), tooltip && tooltip] }), jsx("textarea", { ref: textareaRef, id: fieldId, className: clsx("ids-textarea__textarea", {
|
|
26
|
-
"ids-input--light": light
|
|
26
|
+
"ids-input--light": light,
|
|
27
|
+
"ids-focus-anchor": focusAnchor
|
|
27
28
|
}), "aria-invalid": isInvalid, required: required, "aria-required": required, disabled: disabled, "aria-disabled": disabled, readOnly: readOnly, ...props }), hint && (jsx("div", { id: hintId, className: "ids-input__hint", children: hint })), isInvalid && errorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, children: errorMsg }))] }));
|
|
28
29
|
});
|
|
29
30
|
IDSTextarea.displayName = "IDSTextarea";
|
|
@@ -7,7 +7,7 @@ import { useInputValidity } from '../form-hooks/useInputValidity.js';
|
|
|
7
7
|
import { useAriaDescribedBy } from '../form-hooks/useAriaDescribedBy.js';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
|
|
10
|
-
const IDSTime = forwardRef(({ label = "", errorMsg = "", disabled = false, invalid = false, required = false, noValidation = false, light = false, id, tooltip, className, ...props }, ref) => {
|
|
10
|
+
const IDSTime = forwardRef(({ label = "", errorMsg = "", disabled = false, invalid = false, required = false, noValidation = false, light = false, focusAnchor = false, id, tooltip, className, ...props }, ref) => {
|
|
11
11
|
const fieldId = useElementId(id);
|
|
12
12
|
const errorMsgId = useElementId();
|
|
13
13
|
const inputRef = useRef(null);
|
|
@@ -18,7 +18,8 @@ const IDSTime = forwardRef(({ label = "", errorMsg = "", disabled = false, inval
|
|
|
18
18
|
return (jsxs("div", { className: clsx("ids-time-component", className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { className: clsx("ids-label", {
|
|
19
19
|
"ids-label--disabled": disabled
|
|
20
20
|
}), htmlFor: fieldId, children: label }), tooltip] }), jsx("div", { className: "ids-time", children: jsx("div", { className: "ids-time__input-wrapper", children: jsx("input", { ref: inputRef, id: fieldId, type: "time", className: clsx("ids-time__input", {
|
|
21
|
-
"ids-input--light": light
|
|
21
|
+
"ids-input--light": light,
|
|
22
|
+
"ids-focus-anchor": focusAnchor
|
|
22
23
|
}), "aria-invalid": isInvalid, required: required, "aria-required": required, disabled: disabled, "aria-disabled": disabled, ...props }) }) }), isInvalid && errorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, children: errorMsg }))] }));
|
|
23
24
|
});
|
|
24
25
|
IDSTime.displayName = "IDSTime";
|
|
@@ -2,6 +2,7 @@ import { ReactNode, InputHTMLAttributes } from "react";
|
|
|
2
2
|
interface IDSToggleProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
3
3
|
disabled?: boolean;
|
|
4
4
|
tooltip?: ReactNode;
|
|
5
|
+
focusAnchor?: boolean;
|
|
5
6
|
children?: ReactNode;
|
|
6
7
|
}
|
|
7
8
|
export declare const IDSToggle: import("react").ForwardRefExoticComponent<IDSToggleProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -4,11 +4,13 @@ import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
|
|
7
|
-
const IDSToggle = forwardRef(({ disabled = false, tooltip, id, children, className, ...props }, ref) => {
|
|
7
|
+
const IDSToggle = forwardRef(({ disabled = false, focusAnchor = false, tooltip, id, children, className, ...props }, ref) => {
|
|
8
8
|
const fieldId = useElementId(id);
|
|
9
9
|
const toggleRef = useRef(null);
|
|
10
10
|
useImperativeHandle(ref, () => toggleRef.current);
|
|
11
|
-
return (jsx(Fragment, { children: jsxs("div", { className: clsx("ids-toggle", className), children: [jsx("input", { id: fieldId, ref: toggleRef, className: "ids-toggle__input",
|
|
11
|
+
return (jsx(Fragment, { children: jsxs("div", { className: clsx("ids-toggle", className), children: [jsx("input", { id: fieldId, ref: toggleRef, className: clsx("ids-toggle__input", {
|
|
12
|
+
"ids-focus-anchor": focusAnchor
|
|
13
|
+
}), type: "checkbox", disabled: disabled, ...props }), jsxs("div", { className: "ids-label-tooltip-wrapper ids-label-tooltip-wrapper--inline", children: [jsx("label", { htmlFor: fieldId, className: "ids-toggle__label ids-label ids-label--clickable", children: children }), tooltip] })] }) }));
|
|
12
14
|
});
|
|
13
15
|
IDSToggle.displayName = "IDSToggle";
|
|
14
16
|
|
|
@@ -6,27 +6,40 @@ import clsx from 'clsx';
|
|
|
6
6
|
import { useHeaderContext } from '../utils/contexts/HeaderContext.js';
|
|
7
7
|
|
|
8
8
|
const IDSHeader1177Avatar = ({ username, agent, links, persistent = false }) => {
|
|
9
|
-
const [
|
|
9
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
10
10
|
const headerContext = useHeaderContext();
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const containerRef = useRef(null);
|
|
12
|
+
const dropdownRef = useRef(null);
|
|
13
|
+
const toggleExpanded = () => setIsExpanded(prev => !prev);
|
|
13
14
|
const handleClickOutside = (event) => {
|
|
14
|
-
if (!persistent &&
|
|
15
|
-
|
|
15
|
+
if (!persistent && containerRef.current && !containerRef.current.contains(event.target)) {
|
|
16
|
+
setIsExpanded(false);
|
|
16
17
|
}
|
|
17
18
|
};
|
|
18
19
|
useEffect(() => {
|
|
19
|
-
document.addEventListener("
|
|
20
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
20
21
|
return () => {
|
|
21
|
-
document.removeEventListener("
|
|
22
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
22
23
|
};
|
|
23
24
|
}, [persistent]);
|
|
24
|
-
|
|
25
|
+
const handleLinkClick = () => {
|
|
26
|
+
setIsExpanded(false);
|
|
27
|
+
};
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!persistent && isExpanded) {
|
|
30
|
+
const links = dropdownRef.current?.querySelectorAll("a") || [];
|
|
31
|
+
links.forEach(link => link.addEventListener("click", handleLinkClick));
|
|
32
|
+
return () => {
|
|
33
|
+
links.forEach(link => link.removeEventListener("click", handleLinkClick));
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}, [isExpanded, persistent]);
|
|
37
|
+
return (jsx("div", { ref: containerRef, className: clsx("ids-header-1177-avatar", {
|
|
25
38
|
"ids-header-1177-avatar--unresponsive": headerContext?.unresponsive
|
|
26
39
|
}), children: jsxs("div", { className: "ids-header-1177-avatar__dropdown-wrapper", children: [jsx("button", { className: clsx("ids-header-1177-avatar__button", {
|
|
27
|
-
"ids-header-1177-avatar__button--expanded":
|
|
28
|
-
}), onClick: toggleExpanded, "aria-controls": "ids-header-1177-avatar__dropdown", "aria-expanded":
|
|
29
|
-
"ids-header-1177-avatar__dropdown--expanded":
|
|
40
|
+
"ids-header-1177-avatar__button--expanded": isExpanded
|
|
41
|
+
}), onClick: toggleExpanded, "aria-controls": "ids-header-1177-avatar__dropdown", "aria-expanded": isExpanded, children: jsx("div", { className: "ids-header-1177-avatar-content__name", title: username, children: username }) }), jsxs("div", { ref: dropdownRef, id: "ids-header-1177-avatar__dropdown", className: clsx("ids-header-1177-avatar__dropdown", {
|
|
42
|
+
"ids-header-1177-avatar__dropdown--expanded": isExpanded
|
|
30
43
|
}), children: [agent && jsx("div", { className: "ids-header-1177-avatar__agent", children: agent }), agent && links && jsx("div", { className: "ids-header-1177-avatar__menu-separator" }), links && jsx("div", { className: "ids-header-1177-avatar__menu-links", children: links })] })] }) }));
|
|
31
44
|
};
|
|
32
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import React__default, { useState } from 'react';
|
|
3
|
+
import React__default, { useState, useRef, useEffect } from 'react';
|
|
4
4
|
import '@inera/ids-design/components/header-1177/header-1177-nav-item.css';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { useHeaderContext } from '../utils/contexts/HeaderContext.js';
|
|
@@ -8,18 +8,35 @@ import { useHeaderContext } from '../utils/contexts/HeaderContext.js';
|
|
|
8
8
|
const IDSHeader1177NavItem = ({ active = false, expanded = false, label = "", col1, col2, col3, col4, children }) => {
|
|
9
9
|
const [isExpanded, setIsExpanded] = useState(expanded);
|
|
10
10
|
const headerContext = useHeaderContext();
|
|
11
|
-
const
|
|
11
|
+
const containerRef = useRef(null);
|
|
12
|
+
const handleClickOutside = (event) => {
|
|
13
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
14
|
+
setIsExpanded(false);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setIsExpanded(expanded);
|
|
19
|
+
document.addEventListener("click", handleClickOutside);
|
|
20
|
+
return () => {
|
|
21
|
+
document.removeEventListener("click", handleClickOutside);
|
|
22
|
+
};
|
|
23
|
+
}, [expanded]);
|
|
12
24
|
const renderLink = (link) => {
|
|
13
25
|
return React__default.isValidElement(link)
|
|
14
|
-
? React__default.cloneElement(link, {
|
|
26
|
+
? React__default.cloneElement(link, {
|
|
27
|
+
activeIcon: true,
|
|
28
|
+
block: true,
|
|
29
|
+
colorPreset: 2,
|
|
30
|
+
onClick: () => setIsExpanded(false)
|
|
31
|
+
})
|
|
15
32
|
: link;
|
|
16
33
|
};
|
|
17
34
|
const renderDropdown = () => isExpanded && (jsx("div", { id: "ids-header-1177-nav-dropdown", className: "ids-header-1177__items__item-dropdown", children: jsxs("div", { className: "ids-header-1177__items__item-dropdown__content", children: [jsx("div", { className: "ids-header-1177__items__item-dropdown__content-col-1", children: col1?.map((link, idx) => (jsx("div", { className: "ids-header-1177__items-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177__items__item-dropdown__content-col-2", children: col2?.map((link, idx) => (jsx("div", { className: "ids-header-1177__items-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177__items__item-dropdown__content-col-3", children: col3?.map((link, idx) => (jsx("div", { className: "ids-header-1177__items-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177__items__item-dropdown__content-col-4", children: col4 })] }) }));
|
|
18
|
-
return (jsxs("div", { className: clsx("ids-header-1177__nav-item", {
|
|
35
|
+
return (jsxs("div", { ref: containerRef, className: clsx("ids-header-1177__nav-item", {
|
|
19
36
|
"ids-header-1177__nav-item--unresponsive": headerContext?.unresponsive,
|
|
20
37
|
"ids-header-1177__nav-item--fluid": headerContext?.fluid,
|
|
21
38
|
"ids-header-1177__nav-item--active": active || isExpanded
|
|
22
|
-
}), children: [label ? (jsx("button", { onClick:
|
|
39
|
+
}), children: [label ? (jsx("button", { onClick: () => setIsExpanded(prev => !prev), "aria-expanded": isExpanded, "aria-controls": "ids-header-1177-nav-dropdown", children: label })) : (children), renderDropdown()] }));
|
|
23
40
|
};
|
|
24
41
|
|
|
25
42
|
export { IDSHeader1177NavItem };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import React__default, { useState } from 'react';
|
|
3
|
+
import React__default, { useState, useRef, useEffect } from 'react';
|
|
4
4
|
import '@inera/ids-design/components/header-1177-admin/header-1177-admin-nav-item.css';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { useHeaderContext } from '../utils/contexts/HeaderContext.js';
|
|
@@ -8,20 +8,35 @@ import { useHeaderContext } from '../utils/contexts/HeaderContext.js';
|
|
|
8
8
|
const IDSHeader1177AdminNavItem = ({ active = false, expanded = false, label = "", col1, col2, col3, col4, children }) => {
|
|
9
9
|
const headerContext = useHeaderContext();
|
|
10
10
|
const [isExpanded, setIsExpanded] = useState(expanded);
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const containerRef = useRef(null);
|
|
12
|
+
const handleClickOutside = (event) => {
|
|
13
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
14
|
+
setIsExpanded(false);
|
|
15
|
+
}
|
|
13
16
|
};
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setIsExpanded(expanded);
|
|
19
|
+
document.addEventListener("click", handleClickOutside);
|
|
20
|
+
return () => {
|
|
21
|
+
document.removeEventListener("click", handleClickOutside);
|
|
22
|
+
};
|
|
23
|
+
}, [expanded]);
|
|
14
24
|
const renderLink = (link) => {
|
|
15
25
|
return React__default.isValidElement(link)
|
|
16
|
-
? React__default.cloneElement(link, {
|
|
26
|
+
? React__default.cloneElement(link, {
|
|
27
|
+
activeIcon: true,
|
|
28
|
+
block: true,
|
|
29
|
+
colorPreset: 1,
|
|
30
|
+
onClick: () => setIsExpanded(false)
|
|
31
|
+
})
|
|
17
32
|
: link;
|
|
18
33
|
};
|
|
19
34
|
const renderDropdown = () => isExpanded && (jsx("div", { style: { marginTop: "0.125rem" }, id: "ids-header-1177-admin-nav-dropdown", className: "ids-header-1177-admin__items__item-dropdown", children: jsxs("div", { className: "ids-header-1177-admin__items__item-dropdown__content", children: [jsx("div", { className: "ids-header-1177-admin__items__item-dropdown__content-col-1", children: col1?.map((link, idx) => (jsx("div", { className: "ids-header-1177-admin__items-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177-admin__items__item-dropdown__content-col-2", children: col2?.map((link, idx) => (jsx("div", { className: "ids-header-1177-admin__items-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177-admin__items__item-dropdown__content-col-3", children: col3?.map((link, idx) => (jsx("div", { className: "ids-header-1177-admin__items-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177-admin__items__item-dropdown__content-col-4", children: col4?.map((link, idx) => (jsx("div", { className: "ids-header-1177-admin__items-wrapper", children: renderLink(link) }, idx))) })] }) }));
|
|
20
|
-
return (jsxs("div", { className: clsx("ids-header-1177-admin__nav-item", {
|
|
35
|
+
return (jsxs("div", { ref: containerRef, className: clsx("ids-header-1177-admin__nav-item", {
|
|
21
36
|
"ids-header-1177-admin__nav-item--fluid": headerContext?.fluid,
|
|
22
37
|
"ids-header-1177-admin__nav-item--unresponsive": headerContext?.unresponsive,
|
|
23
38
|
"ids-header-1177-admin__nav-item--active": active || isExpanded
|
|
24
|
-
}), children: [label ? (jsx("button", { onClick:
|
|
39
|
+
}), children: [label ? (jsx("button", { onClick: () => setIsExpanded(prev => !prev), "aria-expanded": isExpanded, "aria-controls": "ids-header-1177-admin-nav-dropdown", children: label })) : (children), renderDropdown()] }));
|
|
25
40
|
};
|
|
26
41
|
|
|
27
42
|
export { IDSHeader1177AdminNavItem };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import React__default, { useState } from 'react';
|
|
3
|
+
import React__default, { useState, useRef, useEffect } from 'react';
|
|
4
4
|
import '@inera/ids-design/components/header-1177-pro/header-1177-pro-nav-item.css';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { useHeaderContext } from '../utils/contexts/HeaderContext.js';
|
|
@@ -8,18 +8,33 @@ import { useHeaderContext } from '../utils/contexts/HeaderContext.js';
|
|
|
8
8
|
const IDSHeader1177ProNavItem = ({ active = false, expanded = false, label = "", col1, col2, col3, col4, children }) => {
|
|
9
9
|
const headerContext = useHeaderContext();
|
|
10
10
|
const [isExpanded, setIsExpanded] = useState(expanded);
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const containerRef = useRef(null);
|
|
12
|
+
const handleClickOutside = (event) => {
|
|
13
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
14
|
+
setIsExpanded(false);
|
|
15
|
+
}
|
|
13
16
|
};
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setIsExpanded(expanded);
|
|
19
|
+
document.addEventListener("click", handleClickOutside);
|
|
20
|
+
return () => {
|
|
21
|
+
document.removeEventListener("click", handleClickOutside);
|
|
22
|
+
};
|
|
23
|
+
}, [expanded]);
|
|
14
24
|
const renderItem = () => {
|
|
15
25
|
if (label) {
|
|
16
|
-
return (jsx("button", { onClick:
|
|
26
|
+
return (jsx("button", { onClick: () => setIsExpanded(prev => !prev), "aria-expanded": isExpanded, "aria-controls": "ids-dropdown", children: label }));
|
|
17
27
|
}
|
|
18
28
|
return children;
|
|
19
29
|
};
|
|
20
30
|
const renderLink = (link) => {
|
|
21
31
|
return React__default.isValidElement(link)
|
|
22
|
-
? React__default.cloneElement(link, {
|
|
32
|
+
? React__default.cloneElement(link, {
|
|
33
|
+
activeIcon: true,
|
|
34
|
+
block: true,
|
|
35
|
+
colorPreset: 1,
|
|
36
|
+
onClick: () => setIsExpanded(false)
|
|
37
|
+
})
|
|
23
38
|
: link;
|
|
24
39
|
};
|
|
25
40
|
const renderDropdown = () => {
|
|
@@ -27,7 +42,7 @@ const IDSHeader1177ProNavItem = ({ active = false, expanded = false, label = "",
|
|
|
27
42
|
return null;
|
|
28
43
|
return (jsx("div", { id: "ids-dropdown", className: "ids-header-1177-pro__items__item-dropdown", children: jsxs("div", { className: "ids-header-1177-pro__items__item-dropdown__content", children: [jsx("div", { className: "ids-header-1177-pro__items__item-dropdown__content-col-1", children: col1?.map((link, idx) => (jsx("div", { className: "ids-header-1177-pro__item-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177-pro__items__item-dropdown__content-col-2", children: col2?.map((link, idx) => (jsx("div", { className: "ids-header-1177-pro__item-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177-pro__items__item-dropdown__content-col-3", children: col3?.map((link, idx) => (jsx("div", { className: "ids-header-1177-pro__item-wrapper", children: renderLink(link) }, idx))) }), jsx("div", { className: "ids-header-1177-pro__items__item-dropdown__content-col-4", children: col4?.map((link, idx) => (jsx("div", { className: "ids-header-1177-pro__item-wrapper", children: renderLink(link) }, idx))) })] }) }));
|
|
29
44
|
};
|
|
30
|
-
return (jsxs("div", { className: clsx("ids-header-1177-pro__nav-item", {
|
|
45
|
+
return (jsxs("div", { ref: containerRef, className: clsx("ids-header-1177-pro__nav-item", {
|
|
31
46
|
"ids-header-1177-pro__nav-item--unresponsive": headerContext?.unresponsive,
|
|
32
47
|
"ids-header-1177-pro__nav-item--active": active || isExpanded
|
|
33
48
|
}), children: [renderItem(), renderDropdown()] }));
|
|
@@ -38,7 +38,12 @@ const IDSHeaderIneraNavItem = ({ label = "", active = false, expanded = false, n
|
|
|
38
38
|
};
|
|
39
39
|
const renderLink = (link) => {
|
|
40
40
|
return React__default.isValidElement(link)
|
|
41
|
-
? React__default.cloneElement(link, {
|
|
41
|
+
? React__default.cloneElement(link, {
|
|
42
|
+
activeIcon: true,
|
|
43
|
+
block: true,
|
|
44
|
+
colorPreset: 2,
|
|
45
|
+
onClick: () => setIsExpanded(false)
|
|
46
|
+
})
|
|
42
47
|
: link;
|
|
43
48
|
};
|
|
44
49
|
const renderContent = () => {
|
|
@@ -38,7 +38,12 @@ const IDSHeaderIneraAdminNavItem = ({ label = "", active = false, expanded = fal
|
|
|
38
38
|
};
|
|
39
39
|
const renderLink = (link) => {
|
|
40
40
|
return React__default.isValidElement(link)
|
|
41
|
-
? React__default.cloneElement(link, {
|
|
41
|
+
? React__default.cloneElement(link, {
|
|
42
|
+
activeIcon: true,
|
|
43
|
+
block: true,
|
|
44
|
+
colorPreset: 2,
|
|
45
|
+
onClick: () => setIsExpanded(false)
|
|
46
|
+
})
|
|
42
47
|
: link;
|
|
43
48
|
};
|
|
44
49
|
const renderContent = () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React, { ReactNode,
|
|
1
|
+
import React, { ReactNode, ReactElement, AnchorHTMLAttributes } from "react";
|
|
2
2
|
export type ColorPreset = 0 | 1 | 2 | 3 | 4;
|
|
3
|
-
export interface IDSLinkProps extends Omit<
|
|
3
|
+
export interface IDSLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "children"> {
|
|
4
4
|
colorPreset?: ColorPreset;
|
|
5
5
|
light?: boolean;
|
|
6
6
|
active?: boolean;
|
|
@@ -12,6 +12,6 @@ export interface IDSLinkProps extends Omit<HTMLAttributes<HTMLElement>, "childre
|
|
|
12
12
|
large?: boolean;
|
|
13
13
|
focusAnchor?: boolean;
|
|
14
14
|
endItem?: ReactNode;
|
|
15
|
-
children
|
|
15
|
+
children?: ReactElement;
|
|
16
16
|
}
|
|
17
17
|
export declare const IDSLink: React.FC<IDSLinkProps>;
|
|
@@ -2,6 +2,7 @@ import React, { ReactNode } from "react";
|
|
|
2
2
|
import "@inera/ids-design/components/puff-list/puff-list.css";
|
|
3
3
|
interface IDSPuffListItemProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
headline?: ReactNode;
|
|
5
|
+
headlineLevel?: 2 | 3 | 4 | 5;
|
|
5
6
|
headlineLink?: React.ReactElement;
|
|
6
7
|
itemLink?: React.ReactElement;
|
|
7
8
|
date?: Date | null;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
-
import { useState, useEffect, isValidElement, cloneElement } from 'react';
|
|
3
|
+
import React__default, { useState, useEffect, isValidElement, cloneElement } from 'react';
|
|
4
4
|
import '@inera/ids-design/components/puff-list/puff-list.css';
|
|
5
5
|
import { getMonthAsSweText, getDayAsText } from '../../utils/utils.js';
|
|
6
6
|
import clsx from 'clsx';
|
|
7
7
|
|
|
8
|
-
const IDSPuffListItem = ({ headline = "", headlineLink, itemLink, date = null, year = "", month = -1, monthLabel = "", day = -1, time = "", noContent = false, noMargin = false, dateLabel, className, children }) => {
|
|
8
|
+
const IDSPuffListItem = ({ headline = "", headlineLevel = 2, headlineLink, itemLink, date = null, year = "", month = -1, monthLabel = "", day = -1, time = "", noContent = false, noMargin = false, dateLabel, className, children }) => {
|
|
9
9
|
const [presentedDate, setPresentedDate] = useState(date);
|
|
10
10
|
useEffect(() => {
|
|
11
11
|
if (date) {
|
|
@@ -31,14 +31,16 @@ const IDSPuffListItem = ({ headline = "", headlineLink, itemLink, date = null, y
|
|
|
31
31
|
"ids-puff-list-item--no-margin": noMargin
|
|
32
32
|
});
|
|
33
33
|
const renderHeadline = () => {
|
|
34
|
+
const level = [2, 3, 4, 5].includes(headlineLevel) ? headlineLevel : 2;
|
|
35
|
+
const Tag = `h${level}`;
|
|
34
36
|
const headlineContent = jsx(Fragment, { children: headline });
|
|
35
37
|
if (headlineLink && isValidElement(headlineLink)) {
|
|
36
|
-
return (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
return React__default.createElement(Tag, { className: getHeaderClass(noMargin) }, cloneElement(headlineLink, {
|
|
39
|
+
...headlineLink.props,
|
|
40
|
+
children: headlineContent
|
|
41
|
+
}));
|
|
40
42
|
}
|
|
41
|
-
return
|
|
43
|
+
return React__default.createElement(Tag, { className: getHeaderClass(noMargin) }, headline);
|
|
42
44
|
};
|
|
43
45
|
const renderBody = () => {
|
|
44
46
|
const content = (jsxs(Fragment, { children: [renderHeadline(), !noContent && jsx("div", { className: "ids-puff-list-item__body", children: children })] }));
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inera/ids-react",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"react": "*"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@inera/ids-core": "7.
|
|
9
|
+
"@inera/ids-core": "7.1.x",
|
|
10
10
|
"@lit-labs/react": "^1.1.0",
|
|
11
11
|
"clsx": "*"
|
|
12
12
|
},
|