@inera/ids-react 7.0.0 → 7.1.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.
- package/components/accordion/accordion.d.ts +1 -0
- package/components/accordion/accordion.js +2 -1
- package/components/button/button.js +1 -0
- package/components/dialog/dialog.js +1 -0
- package/components/dropdown/dropdown.js +2 -2
- package/components/form/check-button/check-button.d.ts +3 -2
- package/components/form/check-button/check-button.js +9 -3
- package/components/form/checkbox/checkbox.d.ts +2 -1
- package/components/form/checkbox/checkbox.js +12 -8
- package/components/form/input/input.d.ts +2 -1
- package/components/form/input/input.js +15 -8
- package/components/form/radio/radio.d.ts +2 -1
- package/components/form/radio/radio.js +8 -5
- package/components/form/radio-button/radio-button.d.ts +3 -2
- package/components/form/radio-button/radio-button.js +9 -5
- package/components/form/range/range.d.ts +2 -1
- package/components/form/range/range.js +8 -4
- package/components/form/select/select.d.ts +2 -1
- package/components/form/select/select.js +7 -4
- package/components/form/select-multiple/select-multiple.d.ts +1 -0
- package/components/form/select-multiple/select-multiple.js +3 -2
- package/components/form/textarea/textarea.d.ts +3 -2
- package/components/form/textarea/textarea.js +7 -4
- package/components/form/time/time.d.ts +3 -2
- package/components/form/time/time.js +11 -8
- package/components/form/toggle/toggle.d.ts +3 -2
- package/components/form/toggle/toggle.js +8 -4
- 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 +2 -0
- package/components/puff-list/puff-list-item/puff-list-item.js +12 -12
- 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
|
|
@@ -94,5 +94,6 @@ const IDSButton = forwardRef(({ active = false, block = false, disabled = false,
|
|
|
94
94
|
: oldIcon;
|
|
95
95
|
return (jsxs("button", { ref: ref, className: classNames, "aria-disabled": disabled || loading, "aria-pressed": toggle, tabIndex: !disabled && !loading ? 0 : -1, disabled: disabled, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, ...props, children: [icon && jsx("span", { className: `ids-icon-${icon}` }), oldIcon && renderOldIcon, children] }));
|
|
96
96
|
});
|
|
97
|
+
IDSButton.displayName = "IDSButton";
|
|
97
98
|
|
|
98
99
|
export { IDSButton };
|
|
@@ -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
|
}
|
|
@@ -60,12 +60,12 @@ const IDSDropdown = ({ expanded = false, persistent = false, position = "right",
|
|
|
60
60
|
key: `dropdown-content-link-${i}`
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
|
-
return (jsx("div", { id: contentId, ref: contentRef, "aria-labelledby": buttonId, className: clsx(
|
|
63
|
+
return (jsx("div", { id: contentId, ref: contentRef, "aria-labelledby": buttonId, className: clsx(`ids-dropdown__content ids-dropdown__content--position-${position}`, {
|
|
64
64
|
"ids-dropdown__content--mblock": mBlock,
|
|
65
65
|
"ids-dropdown__content--sblock": sBlock
|
|
66
66
|
}), ...props, children: enhancedChildren }));
|
|
67
67
|
};
|
|
68
|
-
return (jsxs("span", { className: clsx(`ids-dropdown
|
|
68
|
+
return (jsxs("span", { className: clsx(`ids-dropdown`, className, {
|
|
69
69
|
"ids-dropdown--mblock": mBlock,
|
|
70
70
|
"ids-dropdown--sblock": sBlock
|
|
71
71
|
}), children: [renderTrigger(), isExpanded && renderDropdownContent()] }));
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import
|
|
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
|
-
export declare const IDSCheckButton:
|
|
7
|
+
export declare const IDSCheckButton: import("react").ForwardRefExoticComponent<IDSCheckButtonProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
7
8
|
export {};
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
3
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
4
5
|
import clsx from 'clsx';
|
|
5
6
|
|
|
6
|
-
const IDSCheckButton = ({ disabled = false, id, children, className, ...props }) => {
|
|
7
|
+
const IDSCheckButton = forwardRef(({ disabled = false, focusAnchor = false, id, children, className, ...props }, ref) => {
|
|
7
8
|
const fieldId = useElementId(id);
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
const checkButtonRef = useRef(null);
|
|
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: 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 })] }));
|
|
14
|
+
});
|
|
15
|
+
IDSCheckButton.displayName = "IDSCheckButton";
|
|
10
16
|
|
|
11
17
|
export { IDSCheckButton };
|
|
@@ -9,9 +9,10 @@ export interface IDSCheckboxProps extends InputHTMLAttributes<HTMLInputElement>
|
|
|
9
9
|
light?: boolean;
|
|
10
10
|
block?: boolean;
|
|
11
11
|
compact?: boolean;
|
|
12
|
+
focusAnchor?: boolean;
|
|
12
13
|
errorMsg?: string | ReactNode;
|
|
13
14
|
groupErrorMsgId?: string;
|
|
14
15
|
tooltip?: ReactNode;
|
|
15
16
|
children?: ReactNode;
|
|
16
17
|
}
|
|
17
|
-
export declare const IDSCheckbox: React.
|
|
18
|
+
export declare const IDSCheckbox: React.ForwardRefExoticComponent<IDSCheckboxProps & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef, useEffect } from 'react';
|
|
3
|
+
import { forwardRef, useRef, useEffect } from 'react';
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
6
6
|
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 = ({ 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 }) => {
|
|
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
|
+
const internalRef = useRef(null);
|
|
12
|
+
const checkboxRef = ref ?? internalRef;
|
|
11
13
|
const fieldId = useElementId(id);
|
|
12
14
|
const errorMsgId = useElementId();
|
|
13
|
-
const checkboxRef = useRef(null);
|
|
14
15
|
const hasValidValue = useInputValidity(checkboxRef);
|
|
15
16
|
const isInvalid = (invalid || !hasValidValue) && !noValidation;
|
|
16
17
|
if (groupErrorMsgId) {
|
|
@@ -20,13 +21,13 @@ const IDSCheckbox = ({ invalid = false, disabled = false, required = false, inde
|
|
|
20
21
|
useAriaDescribedBy(checkboxRef, errorMsgId, isInvalid, !!errorMsg);
|
|
21
22
|
}
|
|
22
23
|
useEffect(() => {
|
|
23
|
-
if (
|
|
24
|
+
if (checkboxRef.current) {
|
|
24
25
|
checkboxRef.current.indeterminate = indeterminate;
|
|
25
26
|
}
|
|
26
27
|
}, [checkboxRef, indeterminate]);
|
|
27
28
|
useEffect(() => {
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const checkboxEl = checkboxRef.current;
|
|
30
|
+
if (checkboxEl) {
|
|
30
31
|
const updateAriaChecked = () => {
|
|
31
32
|
checkboxEl.setAttribute("aria-checked", checkboxEl.indeterminate ? "mixed" : `${checkboxEl.checked}`);
|
|
32
33
|
};
|
|
@@ -41,13 +42,16 @@ const IDSCheckbox = ({ invalid = false, disabled = false, required = false, inde
|
|
|
41
42
|
"ids-checkbox--light": light,
|
|
42
43
|
"ids-checkbox--block": block,
|
|
43
44
|
"ids-checkbox--compact": compact
|
|
44
|
-
}), 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: required, "aria-required": required, ...props }), jsxs("div", { className: clsx("ids-label-tooltip-wrapper", {
|
|
45
48
|
"ids-label-tooltip-wrapper--block": block,
|
|
46
49
|
"ids-label-tooltip-wrapper--inline": tooltip
|
|
47
50
|
}), children: [jsx("label", { htmlFor: fieldId, className: clsx("ds-checkbox__label", {
|
|
48
51
|
"ids-label--clickable": disabled,
|
|
49
52
|
"ids-label--no-label": noLabel
|
|
50
53
|
}), children: !noLabel && children }), tooltip] })] }), isInvalid && errorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, compact: true, children: errorMsg }))] }));
|
|
51
|
-
};
|
|
54
|
+
});
|
|
55
|
+
IDSCheckbox.displayName = "IDSCheckbox";
|
|
52
56
|
|
|
53
57
|
export { IDSCheckbox };
|
|
@@ -9,6 +9,7 @@ interface IDSInputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
|
9
9
|
disabled?: boolean;
|
|
10
10
|
invalid?: boolean;
|
|
11
11
|
required?: boolean;
|
|
12
|
+
focusAnchor?: boolean;
|
|
12
13
|
noValidation?: boolean;
|
|
13
14
|
autoSize?: boolean;
|
|
14
15
|
block?: boolean;
|
|
@@ -18,5 +19,5 @@ interface IDSInputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
|
18
19
|
submitButton?: ReactNode;
|
|
19
20
|
oldIcon?: ReactNode;
|
|
20
21
|
}
|
|
21
|
-
export declare const IDSInput: React.
|
|
22
|
+
export declare const IDSInput: React.ForwardRefExoticComponent<IDSInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
22
23
|
export {};
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import React__default, { useRef, useEffect } from 'react';
|
|
3
|
+
import React__default, { forwardRef, useRef, useEffect } from 'react';
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
6
6
|
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 = ({ 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 }) => {
|
|
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();
|
|
14
14
|
const oldIconRef = useRef(null);
|
|
15
15
|
const inputRef = useRef(null);
|
|
16
|
+
const combinedRef = (node) => {
|
|
17
|
+
inputRef.current = node;
|
|
18
|
+
if (typeof ref === "function")
|
|
19
|
+
ref(node);
|
|
20
|
+
else if (ref)
|
|
21
|
+
ref.current = node;
|
|
22
|
+
};
|
|
16
23
|
const hasValidValue = useInputValidity(inputRef);
|
|
17
24
|
const isInvalid = (invalid || !hasValidValue) && !noValidation;
|
|
18
25
|
useAriaDescribedBy(inputRef, errorMsgId, isInvalid, !!errorMsg && !noValidation, !!hint, hintId);
|
|
@@ -36,19 +43,19 @@ const IDSInput = ({ label = "", type = "text", icon = "", hint = "", showSearchL
|
|
|
36
43
|
iconComponent.setAttribute("color", color);
|
|
37
44
|
iconComponent.setAttribute("color2", color2);
|
|
38
45
|
};
|
|
39
|
-
const renderOldIcon = oldIcon && React__default.isValidElement(oldIcon)
|
|
40
|
-
? React__default.cloneElement(oldIcon, { ref: oldIconRef })
|
|
41
|
-
: oldIcon;
|
|
46
|
+
const renderOldIcon = oldIcon && React__default.isValidElement(oldIcon) ? React__default.cloneElement(oldIcon, { ref: oldIconRef }) : oldIcon;
|
|
42
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", {
|
|
43
48
|
"ids-label--disabled": disabled || readOnly,
|
|
44
49
|
"ids-hidden": type === "search" && !showSearchLabel
|
|
45
50
|
}), "aria-hidden": "false", htmlFor: fieldId, children: label }), tooltip] }), jsxs("div", { className: "ids-input__wrapper", children: [jsxs("div", { className: clsx("ids-input__inner-wrapper", {
|
|
46
51
|
"ids-input--icon": icon,
|
|
47
52
|
"ids-input__inner-wrapper--search": type === "search"
|
|
48
|
-
}), children: [jsx("input", { ref:
|
|
53
|
+
}), children: [jsx("input", { ref: combinedRef, id: fieldId, type: type, readOnly: readOnly, className: clsx("ids-input", {
|
|
49
54
|
"ids-input--light": light,
|
|
50
|
-
"ids-input--invalid": invalid
|
|
55
|
+
"ids-input--invalid": invalid,
|
|
56
|
+
"ids-focus-anchor": focusAnchor
|
|
51
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 }))] }));
|
|
52
|
-
};
|
|
58
|
+
});
|
|
59
|
+
IDSInput.displayName = "IDSInput"; // Needed when using forwardRef
|
|
53
60
|
|
|
54
61
|
export { IDSInput };
|
|
@@ -10,8 +10,9 @@ 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;
|
|
16
17
|
}
|
|
17
|
-
export declare const IDSRadio: React.
|
|
18
|
+
export declare const IDSRadio: React.ForwardRefExoticComponent<IDSRadioProps & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef } from 'react';
|
|
3
|
+
import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
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 = ({ name = "", groupErrorMsgId = "", invalid = false, groupInvalid = false, disabled = false, noValidation = false, light = false, compact = false, tooltip, id, children, className, onChange, ...props }) => {
|
|
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
|
+
useImperativeHandle(ref, () => radioRef.current);
|
|
12
13
|
const hasValidValue = useInputValidity(radioRef);
|
|
13
14
|
const isInvalid = (invalid || groupInvalid || !hasValidValue) && !noValidation;
|
|
14
15
|
useAriaDescribedBy(radioRef, groupErrorMsgId, isInvalid, !!groupErrorMsgId);
|
|
15
16
|
return (jsxs("div", { className: clsx("ids-radio", {
|
|
16
17
|
"ids-radio--compact": compact
|
|
17
|
-
}, className), children: [jsx("input", { id: fieldId, ref: radioRef, type: "radio", className: clsx({
|
|
18
|
-
"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
|
|
19
21
|
}), disabled: disabled, "aria-disabled": disabled, "aria-invalid": isInvalid, name: name, onChange: onChange, ...props }), jsxs("div", { className: clsx("ids-label-tooltip-wrapper", {
|
|
20
22
|
"ids-label-tooltip-wrapper--inline": tooltip
|
|
21
23
|
}), children: [jsx("label", { htmlFor: fieldId, className: clsx("ids-radio__label ids-label", {
|
|
22
24
|
"ids-input--clickable": !disabled
|
|
23
25
|
}), children: children }), tooltip] })] }));
|
|
24
|
-
};
|
|
26
|
+
});
|
|
27
|
+
IDSRadio.displayName = "IDSRadio";
|
|
25
28
|
|
|
26
29
|
export { IDSRadio };
|
|
@@ -2,8 +2,9 @@ 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
|
-
onChange?: (e: React.ChangeEvent<HTMLInputElement>) =>
|
|
8
|
+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
8
9
|
}
|
|
9
|
-
export declare const IDSRadioButton: React.
|
|
10
|
+
export declare const IDSRadioButton: React.ForwardRefExoticComponent<IDSRadioButtonProps & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef } from 'react';
|
|
3
|
+
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 = ({ name = "", icon = "user", id, children, onChange, className, ...props }) => {
|
|
7
|
+
const IDSRadioButton = forwardRef(({ name = "", icon = "user", focusAnchor = false, id, children, onChange, className, ...props }, ref) => {
|
|
8
8
|
const fieldId = useElementId(id);
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const radioButtonRef = useRef(null);
|
|
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: 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 })] }));
|
|
14
|
+
});
|
|
15
|
+
IDSRadioButton.displayName = "IDSRadioButton";
|
|
12
16
|
|
|
13
17
|
export { IDSRadioButton };
|
|
@@ -9,8 +9,9 @@ interface IDSRangeProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
|
9
9
|
max?: number;
|
|
10
10
|
step?: number;
|
|
11
11
|
disabled?: boolean;
|
|
12
|
+
focusAnchor?: boolean;
|
|
12
13
|
tooltip?: ReactNode;
|
|
13
14
|
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
14
15
|
}
|
|
15
|
-
export declare const IDSRange: React.
|
|
16
|
+
export declare const IDSRange: React.ForwardRefExoticComponent<IDSRangeProps & React.RefAttributes<HTMLInputElement>>;
|
|
16
17
|
export {};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useState, useRef, useEffect } from 'react';
|
|
3
|
+
import { forwardRef, useState, useRef, useImperativeHandle, useEffect } from 'react';
|
|
4
4
|
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 = ({ label = "", value = 0, showTicks = false, interval = 0, min = 0, max = 0, step = 0, disabled = false, tooltip, id, onChange, className, ...props }) => {
|
|
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);
|
|
12
12
|
const rangeRef = useRef(null);
|
|
13
|
+
useImperativeHandle(ref, () => rangeRef.current);
|
|
13
14
|
useEffect(() => {
|
|
14
15
|
if (step > 0) {
|
|
15
16
|
const steps = [];
|
|
@@ -26,7 +27,10 @@ const IDSRange = ({ label = "", value = 0, showTicks = false, interval = 0, min
|
|
|
26
27
|
onChange(ev);
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
|
-
return (jsxs("div", { className: clsx("ids-range", className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { htmlFor: fieldId, className:
|
|
30
|
-
|
|
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))) }))] }));
|
|
33
|
+
});
|
|
34
|
+
IDSRange.displayName = "IDSRange";
|
|
31
35
|
|
|
32
36
|
export { IDSRange };
|
|
@@ -7,9 +7,10 @@ interface IDSSelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
|
|
7
7
|
required?: boolean;
|
|
8
8
|
invalid?: boolean;
|
|
9
9
|
light?: boolean;
|
|
10
|
+
focusAnchor?: boolean;
|
|
10
11
|
noValidation?: boolean;
|
|
11
12
|
tooltip?: ReactNode;
|
|
12
13
|
children?: ReactNode;
|
|
13
14
|
}
|
|
14
|
-
export declare const IDSSelect: React.
|
|
15
|
+
export declare const IDSSelect: React.ForwardRefExoticComponent<IDSSelectProps & React.RefAttributes<HTMLSelectElement>>;
|
|
15
16
|
export {};
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef } from 'react';
|
|
3
|
+
import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
6
6
|
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 = ({ label = "", srOf = "av", errorMsg = "", disabled = false, required = false, invalid = false, light = false, noValidation = false, tooltip, id, children, className, ...props }) => {
|
|
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);
|
|
14
|
+
useImperativeHandle(ref, () => selectRef.current);
|
|
14
15
|
const hasValidValue = useInputValidity(selectRef);
|
|
15
16
|
const isInvalid = (invalid || !hasValidValue) && !noValidation;
|
|
16
17
|
useAriaDescribedBy(selectRef, errorMsgId, isInvalid, !!errorMsg);
|
|
17
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", {
|
|
18
|
-
"ids-input--light": light
|
|
19
|
+
"ids-input--light": light,
|
|
20
|
+
"ids-focus-anchor": focusAnchor
|
|
19
21
|
}), "aria-invalid": isInvalid, required: required, disabled: disabled, ...props, children: children }) }), isInvalid && errorMsg && (jsx(IDSErrorMessage, { id: errorMsgId, show: true, children: errorMsg }))] }));
|
|
20
|
-
};
|
|
22
|
+
});
|
|
23
|
+
IDSSelect.displayName = "IDSSelect";
|
|
21
24
|
|
|
22
25
|
export { 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,7 +52,8 @@ 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
59
|
}), children: jsx("div", { className: "ids-select-multiple__dropdown__inner", style: { maxHeight: maxHeight }, children: jsx(IDSCheckboxGroup, { block: true, errorMsg: errorMsg, setCheckedBoxesCount: setCheckedBoxesCount, onValidityChange: (isValid) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactNode, TextareaHTMLAttributes } from "react";
|
|
2
2
|
interface IDSTextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
3
3
|
label?: string;
|
|
4
4
|
hint?: string | ReactNode;
|
|
@@ -11,8 +11,9 @@ interface IDSTextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
|
11
11
|
noResize?: boolean;
|
|
12
12
|
block?: boolean;
|
|
13
13
|
light?: boolean;
|
|
14
|
+
focusAnchor?: boolean;
|
|
14
15
|
readOnly?: boolean;
|
|
15
16
|
tooltip?: ReactNode;
|
|
16
17
|
}
|
|
17
|
-
export declare const IDSTextarea:
|
|
18
|
+
export declare const IDSTextarea: import("react").ForwardRefExoticComponent<IDSTextareaProps & import("react").RefAttributes<HTMLTextAreaElement>>;
|
|
18
19
|
export {};
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef } from 'react';
|
|
3
|
+
import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
6
6
|
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 = ({ 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 }) => {
|
|
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();
|
|
14
14
|
const textareaRef = useRef(null);
|
|
15
|
+
useImperativeHandle(ref, () => textareaRef.current);
|
|
15
16
|
const hasValidValue = useInputValidity(textareaRef);
|
|
16
17
|
const isInvalid = (invalid || !hasValidValue) && !noValidation;
|
|
17
18
|
useAriaDescribedBy(textareaRef, errorMsgId, isInvalid, !!errorMsg, !!hint, hintId);
|
|
@@ -22,8 +23,10 @@ const IDSTextarea = ({ label = "", hint, errorMsg = "", disabled = false, invali
|
|
|
22
23
|
}, className), children: [jsxs("div", { className: "ids-label-tooltip-wrapper", children: [jsx("label", { className: clsx("ids-label", {
|
|
23
24
|
"ids-label--disabled": disabled || readOnly
|
|
24
25
|
}), htmlFor: fieldId, children: label }), tooltip && tooltip] }), jsx("textarea", { ref: textareaRef, id: fieldId, className: clsx("ids-textarea__textarea", {
|
|
25
|
-
"ids-input--light": light
|
|
26
|
+
"ids-input--light": light,
|
|
27
|
+
"ids-focus-anchor": focusAnchor
|
|
26
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 }))] }));
|
|
27
|
-
};
|
|
29
|
+
});
|
|
30
|
+
IDSTextarea.displayName = "IDSTextarea";
|
|
28
31
|
|
|
29
32
|
export { IDSTextarea };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactNode, InputHTMLAttributes } from "react";
|
|
2
2
|
interface IDSTimeProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
3
3
|
label?: string;
|
|
4
4
|
errorMsg?: string;
|
|
@@ -6,8 +6,9 @@ interface IDSTimeProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
|
6
6
|
invalid?: boolean;
|
|
7
7
|
required?: boolean;
|
|
8
8
|
noValidation?: boolean;
|
|
9
|
+
focusAnchor?: boolean;
|
|
9
10
|
light?: boolean;
|
|
10
11
|
tooltip?: ReactNode;
|
|
11
12
|
}
|
|
12
|
-
export declare const IDSTime:
|
|
13
|
+
export declare const IDSTime: import("react").ForwardRefExoticComponent<IDSTimeProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
13
14
|
export {};
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef } from 'react';
|
|
3
|
+
import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
4
4
|
import { useElementId } from '../../utils/hooks/useElementId.js';
|
|
5
5
|
import { IDSErrorMessage } from '../error-message/error-message.js';
|
|
6
6
|
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 = ({ label = "", errorMsg = "", disabled = false, invalid = false, required = false, noValidation = false, light = false, id, tooltip, className, ...props }) => {
|
|
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
|
-
const
|
|
14
|
-
|
|
13
|
+
const inputRef = useRef(null);
|
|
14
|
+
useImperativeHandle(ref, () => inputRef.current);
|
|
15
|
+
const hasValidValue = useInputValidity(inputRef);
|
|
15
16
|
const isInvalid = (invalid || !hasValidValue) && !noValidation;
|
|
16
|
-
useAriaDescribedBy(
|
|
17
|
+
useAriaDescribedBy(inputRef, errorMsgId, isInvalid, !!errorMsg);
|
|
17
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", {
|
|
18
19
|
"ids-label--disabled": disabled
|
|
19
|
-
}), htmlFor: fieldId, children: label }), tooltip] }), jsx("div", { className: "ids-time", children: jsx("div", { className: "ids-time__input-wrapper", children: jsx("input", { ref:
|
|
20
|
-
"ids-input--light": light
|
|
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,
|
|
22
|
+
"ids-focus-anchor": focusAnchor
|
|
21
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 }))] }));
|
|
22
|
-
};
|
|
24
|
+
});
|
|
25
|
+
IDSTime.displayName = "IDSTime";
|
|
23
26
|
|
|
24
27
|
export { IDSTime };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
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
|
-
export declare const IDSToggle:
|
|
8
|
+
export declare const IDSToggle: import("react").ForwardRefExoticComponent<IDSToggleProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
8
9
|
export {};
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef } from 'react';
|
|
3
|
+
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 = ({ disabled = false, tooltip, id, children, className, ...props }) => {
|
|
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
|
-
|
|
11
|
-
|
|
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: 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] })] }) }));
|
|
14
|
+
});
|
|
15
|
+
IDSToggle.displayName = "IDSToggle";
|
|
12
16
|
|
|
13
17
|
export { IDSToggle };
|
|
@@ -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;
|
|
@@ -11,6 +12,7 @@ interface IDSPuffListItemProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
11
12
|
day?: number;
|
|
12
13
|
time?: string;
|
|
13
14
|
noContent?: boolean;
|
|
15
|
+
noMargin?: boolean;
|
|
14
16
|
dateLabel?: ReactNode;
|
|
15
17
|
children?: ReactNode;
|
|
16
18
|
}
|
|
@@ -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, 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) {
|
|
@@ -27,23 +27,23 @@ const IDSPuffListItem = ({ headline = "", headlineLink, itemLink, date = null, y
|
|
|
27
27
|
}
|
|
28
28
|
return "";
|
|
29
29
|
};
|
|
30
|
-
const getHeaderClass = (
|
|
31
|
-
"ids-puff-list-item--no-margin":
|
|
30
|
+
const getHeaderClass = (noMargin) => clsx("ids-puff-list-item__header", {
|
|
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
|
-
|
|
45
|
-
return null;
|
|
46
|
-
const content = (jsxs(Fragment, { children: [renderHeadline(), jsx("div", { className: "ids-puff-list-item__body", children: children })] }));
|
|
46
|
+
const content = (jsxs(Fragment, { children: [renderHeadline(), !noContent && jsx("div", { className: "ids-puff-list-item__body", children: children })] }));
|
|
47
47
|
if (itemLink && isValidElement(itemLink)) {
|
|
48
48
|
return cloneElement(itemLink, {
|
|
49
49
|
...itemLink.props,
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inera/ids-react",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.1.0",
|
|
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
|
},
|