@dbcdk/react-components 0.0.201 → 0.0.203

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.
@@ -7,6 +7,7 @@ var react = require('react');
7
7
  var Tooltip = require('../../../components/overlay/tooltip/Tooltip');
8
8
  var styles = require('./Checkbox.module.css');
9
9
  var InputContainer = require('../input-container/InputContainer');
10
+ var messageIds = require('../input-container/messageIds');
10
11
 
11
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
13
 
@@ -27,6 +28,7 @@ function Checkbox({
27
28
  containerLabel,
28
29
  error,
29
30
  helpText,
31
+ helpTextAddition,
30
32
  orientation = "horizontal",
31
33
  labelWidth = "160px",
32
34
  fullWidth = false,
@@ -67,6 +69,7 @@ function Checkbox({
67
69
  "aria-checked": isChecked,
68
70
  "aria-disabled": disabled || void 0,
69
71
  "aria-invalid": Boolean(error) || void 0,
72
+ "aria-describedby": noContainer ? void 0 : messageIds.getDescribedBy(controlId, { error, helpText }),
70
73
  onClick: toggle,
71
74
  className: [
72
75
  styles__default.default.checkbox,
@@ -94,6 +97,7 @@ function Checkbox({
94
97
  htmlFor: controlId,
95
98
  error,
96
99
  helpText,
100
+ helpTextAddition,
97
101
  orientation,
98
102
  size,
99
103
  labelWidth,
@@ -32,6 +32,7 @@ interface CheckboxProps {
32
32
  containerLabel?: string;
33
33
  error?: string;
34
34
  helpText?: string;
35
+ helpTextAddition?: ReactNode;
35
36
  orientation?: 'vertical' | 'horizontal';
36
37
  labelWidth?: string;
37
38
  fullWidth?: boolean;
@@ -42,5 +43,5 @@ interface CheckboxProps {
42
43
  tooltip?: ReactNode;
43
44
  tooltipPlacement?: TooltipPlacement;
44
45
  }
45
- export declare function Checkbox({ checked: controlled, onChange, variant, disabled, label, labelAs, endAdornment, endAdornmentAriaHidden, labelAction, size, modified, containerLabel, error, helpText, orientation, labelWidth, fullWidth, required, noContainer, id, 'data-cy': dataCy, tooltip, tooltipPlacement, }: CheckboxProps): JSX.Element;
46
+ export declare function Checkbox({ checked: controlled, onChange, variant, disabled, label, labelAs, endAdornment, endAdornmentAriaHidden, labelAction, size, modified, containerLabel, error, helpText, helpTextAddition, orientation, labelWidth, fullWidth, required, noContainer, id, 'data-cy': dataCy, tooltip, tooltipPlacement, }: CheckboxProps): JSX.Element;
46
47
  export {};
@@ -5,6 +5,7 @@ import { useState, useId } from 'react';
5
5
  import { Tooltip } from '../../../components/overlay/tooltip/Tooltip';
6
6
  import styles from './Checkbox.module.css';
7
7
  import { InputContainer } from '../input-container/InputContainer';
8
+ import { getDescribedBy } from '../input-container/messageIds';
8
9
 
9
10
  function Checkbox({
10
11
  checked: controlled,
@@ -21,6 +22,7 @@ function Checkbox({
21
22
  containerLabel,
22
23
  error,
23
24
  helpText,
25
+ helpTextAddition,
24
26
  orientation = "horizontal",
25
27
  labelWidth = "160px",
26
28
  fullWidth = false,
@@ -61,6 +63,7 @@ function Checkbox({
61
63
  "aria-checked": isChecked,
62
64
  "aria-disabled": disabled || void 0,
63
65
  "aria-invalid": Boolean(error) || void 0,
66
+ "aria-describedby": noContainer ? void 0 : getDescribedBy(controlId, { error, helpText }),
64
67
  onClick: toggle,
65
68
  className: [
66
69
  styles.checkbox,
@@ -88,6 +91,7 @@ function Checkbox({
88
91
  htmlFor: controlId,
89
92
  error,
90
93
  helpText,
94
+ helpTextAddition,
91
95
  orientation,
92
96
  size,
93
97
  labelWidth,
@@ -7,6 +7,7 @@ var React = require('react');
7
7
  var useTooltipTrigger = require('../../../components/overlay/tooltip/useTooltipTrigger');
8
8
  var styles = require('./FormSelect.module.css');
9
9
  var InputContainer = require('../input-container/InputContainer');
10
+ var messageIds = require('../input-container/messageIds');
10
11
 
11
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
13
 
@@ -58,6 +59,7 @@ function FormSelect({
58
59
  labelAction,
59
60
  error,
60
61
  helpText,
62
+ helpTextAddition,
61
63
  orientation = "vertical",
62
64
  labelWidth = "160px",
63
65
  fullWidth = true,
@@ -83,7 +85,6 @@ function FormSelect({
83
85
  }) {
84
86
  const generatedId = React__namespace.useId();
85
87
  const controlId = id != null ? id : `select-${generatedId}`;
86
- const describedById = `${controlId}-desc`;
87
88
  const selected = React__namespace.useMemo(
88
89
  () => findSelectedOption(options, selectedValue, datakey),
89
90
  [options, selectedValue, datakey]
@@ -94,12 +95,11 @@ function FormSelect({
94
95
  placement: tooltipPlacement,
95
96
  offset: 8
96
97
  });
97
- const describedBy = (() => {
98
- const ids = [];
99
- if (error || helpText) ids.push(describedById);
100
- if (tooltipEnabled) ids.push(tooltipId);
101
- return ids.length ? ids.join(" ") : void 0;
102
- })();
98
+ const describedBy = messageIds.getDescribedBy(
99
+ controlId,
100
+ { error, helpText },
101
+ tooltipEnabled ? tooltipId : void 0
102
+ );
103
103
  const nativeValue = React__namespace.useMemo(() => {
104
104
  if (selected && selected.value != null) return serializeValue(selected.value, datakey);
105
105
  return "";
@@ -116,7 +116,7 @@ function FormSelect({
116
116
  const opt = options.find((o) => serializeValue(o.value, datakey) === raw);
117
117
  if (opt) onChange(opt.value);
118
118
  };
119
- return /* @__PURE__ */ jsxRuntime.jsxs(
119
+ return /* @__PURE__ */ jsxRuntime.jsx(
120
120
  InputContainer.InputContainer,
121
121
  {
122
122
  label,
@@ -125,67 +125,65 @@ function FormSelect({
125
125
  fullWidth,
126
126
  error,
127
127
  helpText,
128
+ helpTextAddition,
128
129
  orientation,
129
130
  labelWidth,
130
131
  required,
131
132
  modified,
132
- children: [
133
- /* @__PURE__ */ jsxRuntime.jsxs(
134
- "div",
135
- {
136
- className: [
137
- styles__default.default.container,
138
- fullWidth ? styles__default.default.fullWidth : "",
139
- canClear ? styles__default.default.withButton : ""
140
- ].filter(Boolean).join(" "),
141
- children: [
142
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.field, children: [
143
- /* @__PURE__ */ jsxRuntime.jsxs(
144
- "select",
145
- {
146
- ...tooltipEnabled ? triggerProps : {},
147
- id: controlId,
148
- name,
149
- className: [styles__default.default.input, styles__default.default[size], styles__default.default[variant]].filter(Boolean).join(" "),
150
- value: nativeValue,
151
- onChange: handleNativeChange,
152
- disabled,
153
- "aria-invalid": Boolean(error) || void 0,
154
- "aria-describedby": describedBy,
155
- "data-cy": dataCy != null ? dataCy : "formselect",
156
- "data-forminput": true,
157
- children: [
158
- includePlaceholderOption && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: placeholderDisabled, children: placeholder }),
159
- options.map((opt) => {
160
- const v = serializeValue(opt.value, datakey);
161
- return /* @__PURE__ */ jsxRuntime.jsx("option", { value: v, children: opt.label }, v);
162
- })
163
- ]
164
- }
165
- ),
166
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.chevron, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 20 }) })
167
- ] }),
168
- canClear && /* @__PURE__ */ jsxRuntime.jsx(
169
- "button",
133
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
134
+ "div",
135
+ {
136
+ className: [
137
+ styles__default.default.container,
138
+ fullWidth ? styles__default.default.fullWidth : "",
139
+ canClear ? styles__default.default.withButton : ""
140
+ ].filter(Boolean).join(" "),
141
+ children: [
142
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.field, children: [
143
+ /* @__PURE__ */ jsxRuntime.jsxs(
144
+ "select",
170
145
  {
171
- type: "button",
172
- className: styles__default.default.trailingButton,
173
- onClick: (e) => {
174
- e.preventDefault();
175
- e.stopPropagation();
176
- onClear == null ? void 0 : onClear();
177
- },
178
- "aria-label": "Ryd valg",
179
- disabled: !showClear,
180
- "data-cy": dataCy ? `${dataCy}-clear` : "formselect-clear",
181
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 18, "aria-hidden": "true" })
146
+ ...tooltipEnabled ? triggerProps : {},
147
+ id: controlId,
148
+ name,
149
+ className: [styles__default.default.input, styles__default.default[size], styles__default.default[variant]].filter(Boolean).join(" "),
150
+ value: nativeValue,
151
+ onChange: handleNativeChange,
152
+ disabled,
153
+ "aria-invalid": Boolean(error) || void 0,
154
+ "aria-describedby": describedBy,
155
+ "data-cy": dataCy != null ? dataCy : "formselect",
156
+ "data-forminput": true,
157
+ children: [
158
+ includePlaceholderOption && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: placeholderDisabled, children: placeholder }),
159
+ options.map((opt) => {
160
+ const v = serializeValue(opt.value, datakey);
161
+ return /* @__PURE__ */ jsxRuntime.jsx("option", { value: v, children: opt.label }, v);
162
+ })
163
+ ]
182
164
  }
183
- )
184
- ]
185
- }
186
- ),
187
- (error || helpText) && /* @__PURE__ */ jsxRuntime.jsx("span", { id: describedById, style: { display: "none" }, children: error != null ? error : helpText })
188
- ]
165
+ ),
166
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.chevron, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 20 }) })
167
+ ] }),
168
+ canClear && /* @__PURE__ */ jsxRuntime.jsx(
169
+ "button",
170
+ {
171
+ type: "button",
172
+ className: styles__default.default.trailingButton,
173
+ onClick: (e) => {
174
+ e.preventDefault();
175
+ e.stopPropagation();
176
+ onClear == null ? void 0 : onClear();
177
+ },
178
+ "aria-label": "Ryd valg",
179
+ disabled: !showClear,
180
+ "data-cy": dataCy ? `${dataCy}-clear` : "formselect-clear",
181
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 18, "aria-hidden": "true" })
182
+ }
183
+ )
184
+ ]
185
+ }
186
+ )
189
187
  }
190
188
  );
191
189
  }
@@ -31,5 +31,5 @@ export type FormSelectProps<T> = Omit<InputContainerProps, 'children' | 'htmlFor
31
31
  */
32
32
  allowClearWhenRequired?: boolean;
33
33
  };
34
- export declare function FormSelect<T extends string | number | Record<string, any>>({ label, labelAction, error, helpText, orientation, labelWidth, fullWidth, required, tooltip, tooltipPlacement, modified, id, name, options, selectedValue, onChange, placeholder, size, variant, onClear, datakey, dataCy, disabled, includePlaceholderOption, allowClearWhenRequired, }: FormSelectProps<T>): React.ReactNode;
34
+ export declare function FormSelect<T extends string | number | Record<string, any>>({ label, labelAction, error, helpText, helpTextAddition, orientation, labelWidth, fullWidth, required, tooltip, tooltipPlacement, modified, id, name, options, selectedValue, onChange, placeholder, size, variant, onClear, datakey, dataCy, disabled, includePlaceholderOption, allowClearWhenRequired, }: FormSelectProps<T>): React.ReactNode;
35
35
  export {};
@@ -1,10 +1,11 @@
1
1
  'use client';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { ChevronDown, X } from 'lucide-react';
4
4
  import * as React from 'react';
5
5
  import { useTooltipTrigger } from '../../../components/overlay/tooltip/useTooltipTrigger';
6
6
  import styles from './FormSelect.module.css';
7
7
  import { InputContainer } from '../input-container/InputContainer';
8
+ import { getDescribedBy } from '../input-container/messageIds';
8
9
 
9
10
  function isEqualValue(a, b, datakey) {
10
11
  if (a === b) return true;
@@ -33,6 +34,7 @@ function FormSelect({
33
34
  labelAction,
34
35
  error,
35
36
  helpText,
37
+ helpTextAddition,
36
38
  orientation = "vertical",
37
39
  labelWidth = "160px",
38
40
  fullWidth = true,
@@ -58,7 +60,6 @@ function FormSelect({
58
60
  }) {
59
61
  const generatedId = React.useId();
60
62
  const controlId = id != null ? id : `select-${generatedId}`;
61
- const describedById = `${controlId}-desc`;
62
63
  const selected = React.useMemo(
63
64
  () => findSelectedOption(options, selectedValue, datakey),
64
65
  [options, selectedValue, datakey]
@@ -69,12 +70,11 @@ function FormSelect({
69
70
  placement: tooltipPlacement,
70
71
  offset: 8
71
72
  });
72
- const describedBy = (() => {
73
- const ids = [];
74
- if (error || helpText) ids.push(describedById);
75
- if (tooltipEnabled) ids.push(tooltipId);
76
- return ids.length ? ids.join(" ") : void 0;
77
- })();
73
+ const describedBy = getDescribedBy(
74
+ controlId,
75
+ { error, helpText },
76
+ tooltipEnabled ? tooltipId : void 0
77
+ );
78
78
  const nativeValue = React.useMemo(() => {
79
79
  if (selected && selected.value != null) return serializeValue(selected.value, datakey);
80
80
  return "";
@@ -91,7 +91,7 @@ function FormSelect({
91
91
  const opt = options.find((o) => serializeValue(o.value, datakey) === raw);
92
92
  if (opt) onChange(opt.value);
93
93
  };
94
- return /* @__PURE__ */ jsxs(
94
+ return /* @__PURE__ */ jsx(
95
95
  InputContainer,
96
96
  {
97
97
  label,
@@ -100,67 +100,65 @@ function FormSelect({
100
100
  fullWidth,
101
101
  error,
102
102
  helpText,
103
+ helpTextAddition,
103
104
  orientation,
104
105
  labelWidth,
105
106
  required,
106
107
  modified,
107
- children: [
108
- /* @__PURE__ */ jsxs(
109
- "div",
110
- {
111
- className: [
112
- styles.container,
113
- fullWidth ? styles.fullWidth : "",
114
- canClear ? styles.withButton : ""
115
- ].filter(Boolean).join(" "),
116
- children: [
117
- /* @__PURE__ */ jsxs("div", { className: styles.field, children: [
118
- /* @__PURE__ */ jsxs(
119
- "select",
120
- {
121
- ...tooltipEnabled ? triggerProps : {},
122
- id: controlId,
123
- name,
124
- className: [styles.input, styles[size], styles[variant]].filter(Boolean).join(" "),
125
- value: nativeValue,
126
- onChange: handleNativeChange,
127
- disabled,
128
- "aria-invalid": Boolean(error) || void 0,
129
- "aria-describedby": describedBy,
130
- "data-cy": dataCy != null ? dataCy : "formselect",
131
- "data-forminput": true,
132
- children: [
133
- includePlaceholderOption && /* @__PURE__ */ jsx("option", { value: "", disabled: placeholderDisabled, children: placeholder }),
134
- options.map((opt) => {
135
- const v = serializeValue(opt.value, datakey);
136
- return /* @__PURE__ */ jsx("option", { value: v, children: opt.label }, v);
137
- })
138
- ]
139
- }
140
- ),
141
- /* @__PURE__ */ jsx("span", { className: styles.chevron, "aria-hidden": "true", children: /* @__PURE__ */ jsx(ChevronDown, { size: 20 }) })
142
- ] }),
143
- canClear && /* @__PURE__ */ jsx(
144
- "button",
108
+ children: /* @__PURE__ */ jsxs(
109
+ "div",
110
+ {
111
+ className: [
112
+ styles.container,
113
+ fullWidth ? styles.fullWidth : "",
114
+ canClear ? styles.withButton : ""
115
+ ].filter(Boolean).join(" "),
116
+ children: [
117
+ /* @__PURE__ */ jsxs("div", { className: styles.field, children: [
118
+ /* @__PURE__ */ jsxs(
119
+ "select",
145
120
  {
146
- type: "button",
147
- className: styles.trailingButton,
148
- onClick: (e) => {
149
- e.preventDefault();
150
- e.stopPropagation();
151
- onClear == null ? void 0 : onClear();
152
- },
153
- "aria-label": "Ryd valg",
154
- disabled: !showClear,
155
- "data-cy": dataCy ? `${dataCy}-clear` : "formselect-clear",
156
- children: /* @__PURE__ */ jsx(X, { size: 18, "aria-hidden": "true" })
121
+ ...tooltipEnabled ? triggerProps : {},
122
+ id: controlId,
123
+ name,
124
+ className: [styles.input, styles[size], styles[variant]].filter(Boolean).join(" "),
125
+ value: nativeValue,
126
+ onChange: handleNativeChange,
127
+ disabled,
128
+ "aria-invalid": Boolean(error) || void 0,
129
+ "aria-describedby": describedBy,
130
+ "data-cy": dataCy != null ? dataCy : "formselect",
131
+ "data-forminput": true,
132
+ children: [
133
+ includePlaceholderOption && /* @__PURE__ */ jsx("option", { value: "", disabled: placeholderDisabled, children: placeholder }),
134
+ options.map((opt) => {
135
+ const v = serializeValue(opt.value, datakey);
136
+ return /* @__PURE__ */ jsx("option", { value: v, children: opt.label }, v);
137
+ })
138
+ ]
157
139
  }
158
- )
159
- ]
160
- }
161
- ),
162
- (error || helpText) && /* @__PURE__ */ jsx("span", { id: describedById, style: { display: "none" }, children: error != null ? error : helpText })
163
- ]
140
+ ),
141
+ /* @__PURE__ */ jsx("span", { className: styles.chevron, "aria-hidden": "true", children: /* @__PURE__ */ jsx(ChevronDown, { size: 20 }) })
142
+ ] }),
143
+ canClear && /* @__PURE__ */ jsx(
144
+ "button",
145
+ {
146
+ type: "button",
147
+ className: styles.trailingButton,
148
+ onClick: (e) => {
149
+ e.preventDefault();
150
+ e.stopPropagation();
151
+ onClear == null ? void 0 : onClear();
152
+ },
153
+ "aria-label": "Ryd valg",
154
+ disabled: !showClear,
155
+ "data-cy": dataCy ? `${dataCy}-clear` : "formselect-clear",
156
+ children: /* @__PURE__ */ jsx(X, { size: 18, "aria-hidden": "true" })
157
+ }
158
+ )
159
+ ]
160
+ }
161
+ )
164
162
  }
165
163
  );
166
164
  }
@@ -8,6 +8,7 @@ var ClearButton = require('../../../components/clear-button/ClearButton');
8
8
  var useTooltipTrigger = require('../../../components/overlay/tooltip/useTooltipTrigger');
9
9
  var styles = require('../input/Input.module.css');
10
10
  var InputContainer = require('../input-container/InputContainer');
11
+ var messageIds = require('../input-container/messageIds');
11
12
 
12
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
14
 
@@ -27,6 +28,7 @@ const Input = react.forwardRef(function Input2({
27
28
  labelAction,
28
29
  error,
29
30
  helpText,
31
+ helpTextAddition,
30
32
  orientation = "vertical",
31
33
  labelWidth = "160px",
32
34
  fullWidth = false,
@@ -97,6 +99,7 @@ const Input = react.forwardRef(function Input2({
97
99
  fullWidth,
98
100
  error,
99
101
  helpText,
102
+ helpTextAddition,
100
103
  orientation,
101
104
  labelWidth,
102
105
  required,
@@ -138,6 +141,11 @@ const Input = react.forwardRef(function Input2({
138
141
  {
139
142
  ...inputProps,
140
143
  id: inputId,
144
+ "aria-describedby": messageIds.getDescribedBy(
145
+ inputId,
146
+ { error, helpText },
147
+ inputProps["aria-describedby"]
148
+ ),
141
149
  ref: mergeRefs(inputRef, ref),
142
150
  className: [styles__default.default.input, inputSize ? styles__default.default[inputSize] : "", inputClassName != null ? inputClassName : ""].filter(Boolean).join(" ")
143
151
  }
@@ -6,6 +6,7 @@ import { ClearButton } from '../../../components/clear-button/ClearButton';
6
6
  import { useTooltipTrigger } from '../../../components/overlay/tooltip/useTooltipTrigger';
7
7
  import styles from '../input/Input.module.css';
8
8
  import { InputContainer } from '../input-container/InputContainer';
9
+ import { getDescribedBy } from '../input-container/messageIds';
9
10
 
10
11
  function mergeRefs(...refs) {
11
12
  return (node) => {
@@ -21,6 +22,7 @@ const Input = forwardRef(function Input2({
21
22
  labelAction,
22
23
  error,
23
24
  helpText,
25
+ helpTextAddition,
24
26
  orientation = "vertical",
25
27
  labelWidth = "160px",
26
28
  fullWidth = false,
@@ -91,6 +93,7 @@ const Input = forwardRef(function Input2({
91
93
  fullWidth,
92
94
  error,
93
95
  helpText,
96
+ helpTextAddition,
94
97
  orientation,
95
98
  labelWidth,
96
99
  required,
@@ -132,6 +135,11 @@ const Input = forwardRef(function Input2({
132
135
  {
133
136
  ...inputProps,
134
137
  id: inputId,
138
+ "aria-describedby": getDescribedBy(
139
+ inputId,
140
+ { error, helpText },
141
+ inputProps["aria-describedby"]
142
+ ),
135
143
  ref: mergeRefs(inputRef, ref),
136
144
  className: [styles.input, inputSize ? styles[inputSize] : "", inputClassName != null ? inputClassName : ""].filter(Boolean).join(" ")
137
145
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var styles = require('./InputContainer.module.css');
5
+ var messageIds = require('./messageIds');
5
6
  var InlineStatus = require('../../inline-status/InlineStatus');
6
7
 
7
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -31,10 +32,14 @@ function InputContainer({
31
32
  ] }),
32
33
  labelAction && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-input-container-label-action": "true", children: labelAction })
33
34
  ] });
34
- const renderMessageRow = (error || helpText || helpTextAddition) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${error ? styles__default.default.errorText : styles__default.default.helpText} ${styles__default.default.messageRow}`, children: error ? /* @__PURE__ */ jsxRuntime.jsx(InlineStatus.InlineStatus, { severity: "error", disableIcon: true, children: error }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
35
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: helpText }),
36
- helpTextAddition && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.helpTextAddition, children: helpTextAddition })
37
- ] }) });
35
+ const messageIds$1 = htmlFor ? messageIds.getMessageIds(htmlFor) : void 0;
36
+ const renderMessageRow = (error || helpText || helpTextAddition) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dbc-flex dbc-flex-column dbc-gap-xxs", children: [
37
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { id: messageIds$1 == null ? void 0 : messageIds$1.errorId, className: `${styles__default.default.errorText} ${styles__default.default.messageRow}`, children: /* @__PURE__ */ jsxRuntime.jsx(InlineStatus.InlineStatus, { severity: "error", disableIcon: true, children: error }) }),
38
+ (helpText || helpTextAddition) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.helpText} ${styles__default.default.messageRow}`, children: [
39
+ /* @__PURE__ */ jsxRuntime.jsx("span", { id: messageIds$1 == null ? void 0 : messageIds$1.helpTextId, children: helpText }),
40
+ helpTextAddition && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.helpTextAddition, children: helpTextAddition })
41
+ ] })
42
+ ] });
38
43
  if (orientation === "vertical") {
39
44
  return /* @__PURE__ */ jsxRuntime.jsxs(
40
45
  "div",
@@ -1,5 +1,6 @@
1
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import styles from './InputContainer.module.css';
3
+ import { getMessageIds } from './messageIds';
3
4
  import { InlineStatus } from '../../inline-status/InlineStatus';
4
5
 
5
6
  function InputContainer({
@@ -25,10 +26,14 @@ function InputContainer({
25
26
  ] }),
26
27
  labelAction && /* @__PURE__ */ jsx("span", { "data-input-container-label-action": "true", children: labelAction })
27
28
  ] });
28
- const renderMessageRow = (error || helpText || helpTextAddition) && /* @__PURE__ */ jsx("div", { className: `${error ? styles.errorText : styles.helpText} ${styles.messageRow}`, children: error ? /* @__PURE__ */ jsx(InlineStatus, { severity: "error", disableIcon: true, children: error }) : /* @__PURE__ */ jsxs(Fragment, { children: [
29
- /* @__PURE__ */ jsx("span", { children: helpText }),
30
- helpTextAddition && /* @__PURE__ */ jsx("span", { className: styles.helpTextAddition, children: helpTextAddition })
31
- ] }) });
29
+ const messageIds = htmlFor ? getMessageIds(htmlFor) : void 0;
30
+ const renderMessageRow = (error || helpText || helpTextAddition) && /* @__PURE__ */ jsxs("div", { className: "dbc-flex dbc-flex-column dbc-gap-xxs", children: [
31
+ error && /* @__PURE__ */ jsx("div", { id: messageIds == null ? void 0 : messageIds.errorId, className: `${styles.errorText} ${styles.messageRow}`, children: /* @__PURE__ */ jsx(InlineStatus, { severity: "error", disableIcon: true, children: error }) }),
32
+ (helpText || helpTextAddition) && /* @__PURE__ */ jsxs("div", { className: `${styles.helpText} ${styles.messageRow}`, children: [
33
+ /* @__PURE__ */ jsx("span", { id: messageIds == null ? void 0 : messageIds.helpTextId, children: helpText }),
34
+ helpTextAddition && /* @__PURE__ */ jsx("span", { className: styles.helpTextAddition, children: helpTextAddition })
35
+ ] })
36
+ ] });
32
37
  if (orientation === "vertical") {
33
38
  return /* @__PURE__ */ jsxs(
34
39
  "div",
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ function getMessageIds(controlId) {
4
+ return { errorId: `${controlId}-error`, helpTextId: `${controlId}-help` };
5
+ }
6
+ function getDescribedBy(controlId, { error, helpText }, ...extraIds) {
7
+ const { errorId, helpTextId } = getMessageIds(controlId);
8
+ const ids = [error ? errorId : void 0, helpText ? helpTextId : void 0, ...extraIds].filter(
9
+ Boolean
10
+ );
11
+ return ids.length ? ids.join(" ") : void 0;
12
+ }
13
+
14
+ exports.getDescribedBy = getDescribedBy;
15
+ exports.getMessageIds = getMessageIds;
@@ -0,0 +1,13 @@
1
+ /** Ids of the error and help text that InputContainer renders for a control with id `controlId`. */
2
+ export declare function getMessageIds(controlId: string): {
3
+ errorId: string;
4
+ helpTextId: string;
5
+ };
6
+ /**
7
+ * aria-describedby value for a control inside InputContainer: the rendered error and help text,
8
+ * followed by any extra ids (e.g. a tooltip or the consumer's own aria-describedby).
9
+ */
10
+ export declare function getDescribedBy(controlId: string, { error, helpText }: {
11
+ error?: unknown;
12
+ helpText?: unknown;
13
+ }, ...extraIds: Array<string | undefined | null | false>): string | undefined;
@@ -0,0 +1,12 @@
1
+ function getMessageIds(controlId) {
2
+ return { errorId: `${controlId}-error`, helpTextId: `${controlId}-help` };
3
+ }
4
+ function getDescribedBy(controlId, { error, helpText }, ...extraIds) {
5
+ const { errorId, helpTextId } = getMessageIds(controlId);
6
+ const ids = [error ? errorId : void 0, helpText ? helpTextId : void 0, ...extraIds].filter(
7
+ Boolean
8
+ );
9
+ return ids.length ? ids.join(" ") : void 0;
10
+ }
11
+
12
+ export { getDescribedBy, getMessageIds };
@@ -10,6 +10,7 @@ var ClearButton = require('../../clear-button/ClearButton');
10
10
  var Menu = require('../../menu/Menu');
11
11
  var Popover = require('../../popover/Popover');
12
12
  var InputContainer = require('../input-container/InputContainer');
13
+ var messageIds = require('../input-container/messageIds');
13
14
 
14
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
16
 
@@ -20,6 +21,7 @@ function Select({
20
21
  labelAction,
21
22
  error,
22
23
  helpText,
24
+ helpTextAddition,
23
25
  orientation = "vertical",
24
26
  labelWidth = "160px",
25
27
  fullWidth = true,
@@ -43,7 +45,6 @@ function Select({
43
45
  }) {
44
46
  const generatedId = react.useId();
45
47
  const controlId = id != null ? id : `select-${generatedId}`;
46
- const describedById = `${controlId}-desc`;
47
48
  const listboxId = `${controlId}-listbox`;
48
49
  const popoverRef = react.useRef(null);
49
50
  const triggerRef = react.useRef(null);
@@ -62,10 +63,15 @@ function Select({
62
63
  };
63
64
  }, []);
64
65
  react.useEffect(() => {
65
- var _a, _b, _c;
66
66
  if (!open) return;
67
- (_a = optionRefs.current[activeIndex]) == null ? void 0 : _a.focus();
68
- (_c = (_b = optionRefs.current[activeIndex]) == null ? void 0 : _b.scrollIntoView) == null ? void 0 : _c.call(_b, { block: "nearest" });
67
+ const focusActive = () => {
68
+ var _a, _b, _c;
69
+ (_a = optionRefs.current[activeIndex]) == null ? void 0 : _a.focus();
70
+ (_c = (_b = optionRefs.current[activeIndex]) == null ? void 0 : _b.scrollIntoView) == null ? void 0 : _c.call(_b, { block: "nearest" });
71
+ };
72
+ focusActive();
73
+ const frame = requestAnimationFrame(focusActive);
74
+ return () => cancelAnimationFrame(frame);
69
75
  }, [activeIndex, open]);
70
76
  const resetActiveToSelected = () => setActiveIndex(selectedIndex >= 0 ? selectedIndex : 0);
71
77
  const findTypeaheadMatch = (query, startIndex) => {
@@ -174,13 +180,12 @@ function Select({
174
180
  placement: tooltipPlacement,
175
181
  offset: 8
176
182
  });
177
- const describedBy = (() => {
178
- const ids = [];
179
- if (error || helpText) ids.push(describedById);
180
- if (tooltipEnabled) ids.push(tooltipId);
181
- return ids.length ? ids.join(" ") : void 0;
182
- })();
183
- return /* @__PURE__ */ jsxRuntime.jsxs(
183
+ const describedBy = messageIds.getDescribedBy(
184
+ controlId,
185
+ { error, helpText },
186
+ tooltipEnabled ? tooltipId : void 0
187
+ );
188
+ return /* @__PURE__ */ jsxRuntime.jsx(
184
189
  InputContainer.InputContainer,
185
190
  {
186
191
  label,
@@ -189,116 +194,114 @@ function Select({
189
194
  fullWidth,
190
195
  error,
191
196
  helpText,
197
+ helpTextAddition,
192
198
  orientation,
193
199
  labelWidth,
194
200
  required,
195
201
  modified,
196
- children: [
197
- /* @__PURE__ */ jsxRuntime.jsx(
198
- Popover.Popover,
199
- {
200
- ref: popoverRef,
201
- anchorRef: triggerRef,
202
- open,
203
- fullWidth,
204
- onOpenChange: (next) => {
205
- setOpen(next);
206
- if (next) resetActiveToSelected();
207
- },
208
- contentId: listboxId,
209
- autoFocusContent: false,
210
- returnFocus: true,
211
- trigger: (toggle, icon, isOpen) => /* @__PURE__ */ jsxRuntime.jsx(
212
- Button.Button,
213
- {
214
- disabled,
215
- ...tooltipEnabled ? triggerProps : {},
216
- ref: (node) => {
217
- triggerRef.current = node;
218
- if (tooltipEnabled) triggerProps.ref(node);
202
+ children: /* @__PURE__ */ jsxRuntime.jsx(
203
+ Popover.Popover,
204
+ {
205
+ ref: popoverRef,
206
+ anchorRef: triggerRef,
207
+ open,
208
+ fullWidth,
209
+ onOpenChange: (next) => {
210
+ setOpen(next);
211
+ if (next) resetActiveToSelected();
212
+ },
213
+ contentId: listboxId,
214
+ autoFocusContent: false,
215
+ returnFocus: true,
216
+ trigger: (toggle, icon, isOpen) => /* @__PURE__ */ jsxRuntime.jsx(
217
+ Button.Button,
218
+ {
219
+ disabled,
220
+ ...tooltipEnabled ? triggerProps : {},
221
+ ref: (node) => {
222
+ triggerRef.current = node;
223
+ if (tooltipEnabled) triggerProps.ref(node);
224
+ },
225
+ id: controlId,
226
+ "data-cy": dataCy != null ? dataCy : "select-button",
227
+ onKeyDown: handleKeyDown,
228
+ fullWidth,
229
+ variant,
230
+ onClick: (e) => {
231
+ resetActiveToSelected();
232
+ toggle(e);
233
+ },
234
+ size,
235
+ style: minWidth != null ? { minWidth } : void 0,
236
+ type: "button",
237
+ "data-forminput": true,
238
+ "aria-haspopup": "listbox",
239
+ "aria-expanded": !!isOpen,
240
+ "aria-controls": listboxId,
241
+ "aria-invalid": Boolean(error) || void 0,
242
+ "aria-describedby": describedBy,
243
+ className: modified ? styles__default.default.triggerModified : void 0,
244
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
245
+ "span",
246
+ {
247
+ className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs",
248
+ style: { width: "100%" },
249
+ children: [
250
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: selected ? selected.label : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dbc-muted-text", children: placeholder }) }),
251
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [
252
+ onClear && selected && /* @__PURE__ */ jsxRuntime.jsx(
253
+ ClearButton.ClearButton,
254
+ {
255
+ onClick: onClear,
256
+ variant: variant === "header" ? "header" : "default",
257
+ as: "span",
258
+ revealOnHover: true
259
+ }
260
+ ),
261
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
262
+ ] })
263
+ ]
264
+ }
265
+ )
266
+ }
267
+ ),
268
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, { onKeyDownCapture: handleKeyDown, role: "listbox", className: styles__default.default.menu, children: [
269
+ menuHeader ? /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Header, { children: menuHeader }) : null,
270
+ options.map((opt, index) => {
271
+ const isSelected = typeof opt.value === "object" && typeof selectedValue === "object" && datakey ? (selectedValue == null ? void 0 : selectedValue[datakey]) === opt.value[datakey] : opt.value === selectedValue;
272
+ const isActive = index === activeIndex;
273
+ return /* @__PURE__ */ jsxRuntime.jsx(
274
+ Menu.Menu.Item,
275
+ {
276
+ active: isActive,
277
+ selected: isSelected,
278
+ itemRole: "option",
279
+ className: isSelected ? styles__default.default.selectedOption : void 0,
280
+ children: /* @__PURE__ */ jsxRuntime.jsx(
281
+ "button",
282
+ {
283
+ ref: (el) => {
284
+ optionRefs.current[index] = el;
285
+ },
286
+ type: "button",
287
+ tabIndex: isActive ? 0 : -1,
288
+ onClick: () => {
289
+ var _a;
290
+ onChange(opt.value);
291
+ (_a = popoverRef.current) == null ? void 0 : _a.close();
292
+ },
293
+ onFocus: () => setActiveIndex(index),
294
+ style: { display: "flex", alignItems: "center", width: "100%" },
295
+ children: opt.label
296
+ }
297
+ )
219
298
  },
220
- id: controlId,
221
- "data-cy": dataCy != null ? dataCy : "select-button",
222
- onKeyDown: handleKeyDown,
223
- fullWidth,
224
- variant,
225
- onClick: (e) => {
226
- resetActiveToSelected();
227
- toggle(e);
228
- },
229
- size,
230
- style: minWidth != null ? { minWidth } : void 0,
231
- type: "button",
232
- "data-forminput": true,
233
- "aria-haspopup": "listbox",
234
- "aria-expanded": !!isOpen,
235
- "aria-controls": listboxId,
236
- "aria-invalid": Boolean(error) || void 0,
237
- "aria-describedby": describedBy,
238
- className: modified ? styles__default.default.triggerModified : void 0,
239
- children: /* @__PURE__ */ jsxRuntime.jsxs(
240
- "span",
241
- {
242
- className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs",
243
- style: { width: "100%" },
244
- children: [
245
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: selected ? selected.label : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dbc-muted-text", children: placeholder }) }),
246
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [
247
- onClear && selected && /* @__PURE__ */ jsxRuntime.jsx(
248
- ClearButton.ClearButton,
249
- {
250
- onClick: onClear,
251
- variant: variant === "header" ? "header" : "default",
252
- as: "span",
253
- revealOnHover: true
254
- }
255
- ),
256
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
257
- ] })
258
- ]
259
- }
260
- )
261
- }
262
- ),
263
- children: /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, { onKeyDownCapture: handleKeyDown, role: "listbox", className: styles__default.default.menu, children: [
264
- menuHeader ? /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Header, { children: menuHeader }) : null,
265
- options.map((opt, index) => {
266
- const isSelected = typeof opt.value === "object" && typeof selectedValue === "object" && datakey ? (selectedValue == null ? void 0 : selectedValue[datakey]) === opt.value[datakey] : opt.value === selectedValue;
267
- const isActive = index === activeIndex;
268
- return /* @__PURE__ */ jsxRuntime.jsx(
269
- Menu.Menu.Item,
270
- {
271
- active: isActive,
272
- selected: isSelected,
273
- itemRole: "option",
274
- className: isSelected ? styles__default.default.selectedOption : void 0,
275
- children: /* @__PURE__ */ jsxRuntime.jsx(
276
- "button",
277
- {
278
- ref: (el) => {
279
- optionRefs.current[index] = el;
280
- },
281
- type: "button",
282
- tabIndex: isActive ? 0 : -1,
283
- onClick: () => {
284
- var _a;
285
- onChange(opt.value);
286
- (_a = popoverRef.current) == null ? void 0 : _a.close();
287
- },
288
- onFocus: () => setActiveIndex(index),
289
- style: { display: "flex", alignItems: "center", width: "100%" },
290
- children: opt.label
291
- }
292
- )
293
- },
294
- String(opt.value)
295
- );
296
- })
297
- ] })
298
- }
299
- ),
300
- (error || helpText) && /* @__PURE__ */ jsxRuntime.jsx("span", { id: describedById, style: { display: "none" }, children: error != null ? error : helpText })
301
- ]
299
+ String(opt.value)
300
+ );
301
+ })
302
+ ] })
303
+ }
304
+ )
302
305
  }
303
306
  );
304
307
  }
@@ -20,5 +20,5 @@ export type SelectProps<T> = Omit<InputContainerProps, 'children' | 'htmlFor' |
20
20
  tooltip?: React.ReactNode;
21
21
  tooltipPlacement?: 'top' | 'right' | 'bottom' | 'left';
22
22
  };
23
- export declare function Select<T extends string | number | Record<string, any>>({ label, labelAction, error, helpText, orientation, labelWidth, fullWidth, required, tooltip, tooltipPlacement, modified, id, options, selectedValue, onChange, placeholder, size, variant, onClear, datakey, dataCy, disabled, minWidth, menuHeader, }: SelectProps<T>): React.ReactNode;
23
+ export declare function Select<T extends string | number | Record<string, any>>({ label, labelAction, error, helpText, helpTextAddition, orientation, labelWidth, fullWidth, required, tooltip, tooltipPlacement, modified, id, options, selectedValue, onChange, placeholder, size, variant, onClear, datakey, dataCy, disabled, minWidth, menuHeader, }: SelectProps<T>): React.ReactNode;
24
24
  export {};
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { useId, useRef, useMemo, useState, useEffect } from 'react';
4
4
  import { useTooltipTrigger } from '../../../components/overlay/tooltip/useTooltipTrigger';
5
5
  import styles from './Select.module.css';
@@ -8,12 +8,14 @@ import { ClearButton } from '../../clear-button/ClearButton';
8
8
  import { Menu } from '../../menu/Menu';
9
9
  import { Popover } from '../../popover/Popover';
10
10
  import { InputContainer } from '../input-container/InputContainer';
11
+ import { getDescribedBy } from '../input-container/messageIds';
11
12
 
12
13
  function Select({
13
14
  label,
14
15
  labelAction,
15
16
  error,
16
17
  helpText,
18
+ helpTextAddition,
17
19
  orientation = "vertical",
18
20
  labelWidth = "160px",
19
21
  fullWidth = true,
@@ -37,7 +39,6 @@ function Select({
37
39
  }) {
38
40
  const generatedId = useId();
39
41
  const controlId = id != null ? id : `select-${generatedId}`;
40
- const describedById = `${controlId}-desc`;
41
42
  const listboxId = `${controlId}-listbox`;
42
43
  const popoverRef = useRef(null);
43
44
  const triggerRef = useRef(null);
@@ -56,10 +57,15 @@ function Select({
56
57
  };
57
58
  }, []);
58
59
  useEffect(() => {
59
- var _a, _b, _c;
60
60
  if (!open) return;
61
- (_a = optionRefs.current[activeIndex]) == null ? void 0 : _a.focus();
62
- (_c = (_b = optionRefs.current[activeIndex]) == null ? void 0 : _b.scrollIntoView) == null ? void 0 : _c.call(_b, { block: "nearest" });
61
+ const focusActive = () => {
62
+ var _a, _b, _c;
63
+ (_a = optionRefs.current[activeIndex]) == null ? void 0 : _a.focus();
64
+ (_c = (_b = optionRefs.current[activeIndex]) == null ? void 0 : _b.scrollIntoView) == null ? void 0 : _c.call(_b, { block: "nearest" });
65
+ };
66
+ focusActive();
67
+ const frame = requestAnimationFrame(focusActive);
68
+ return () => cancelAnimationFrame(frame);
63
69
  }, [activeIndex, open]);
64
70
  const resetActiveToSelected = () => setActiveIndex(selectedIndex >= 0 ? selectedIndex : 0);
65
71
  const findTypeaheadMatch = (query, startIndex) => {
@@ -168,13 +174,12 @@ function Select({
168
174
  placement: tooltipPlacement,
169
175
  offset: 8
170
176
  });
171
- const describedBy = (() => {
172
- const ids = [];
173
- if (error || helpText) ids.push(describedById);
174
- if (tooltipEnabled) ids.push(tooltipId);
175
- return ids.length ? ids.join(" ") : void 0;
176
- })();
177
- return /* @__PURE__ */ jsxs(
177
+ const describedBy = getDescribedBy(
178
+ controlId,
179
+ { error, helpText },
180
+ tooltipEnabled ? tooltipId : void 0
181
+ );
182
+ return /* @__PURE__ */ jsx(
178
183
  InputContainer,
179
184
  {
180
185
  label,
@@ -183,116 +188,114 @@ function Select({
183
188
  fullWidth,
184
189
  error,
185
190
  helpText,
191
+ helpTextAddition,
186
192
  orientation,
187
193
  labelWidth,
188
194
  required,
189
195
  modified,
190
- children: [
191
- /* @__PURE__ */ jsx(
192
- Popover,
193
- {
194
- ref: popoverRef,
195
- anchorRef: triggerRef,
196
- open,
197
- fullWidth,
198
- onOpenChange: (next) => {
199
- setOpen(next);
200
- if (next) resetActiveToSelected();
201
- },
202
- contentId: listboxId,
203
- autoFocusContent: false,
204
- returnFocus: true,
205
- trigger: (toggle, icon, isOpen) => /* @__PURE__ */ jsx(
206
- Button,
207
- {
208
- disabled,
209
- ...tooltipEnabled ? triggerProps : {},
210
- ref: (node) => {
211
- triggerRef.current = node;
212
- if (tooltipEnabled) triggerProps.ref(node);
196
+ children: /* @__PURE__ */ jsx(
197
+ Popover,
198
+ {
199
+ ref: popoverRef,
200
+ anchorRef: triggerRef,
201
+ open,
202
+ fullWidth,
203
+ onOpenChange: (next) => {
204
+ setOpen(next);
205
+ if (next) resetActiveToSelected();
206
+ },
207
+ contentId: listboxId,
208
+ autoFocusContent: false,
209
+ returnFocus: true,
210
+ trigger: (toggle, icon, isOpen) => /* @__PURE__ */ jsx(
211
+ Button,
212
+ {
213
+ disabled,
214
+ ...tooltipEnabled ? triggerProps : {},
215
+ ref: (node) => {
216
+ triggerRef.current = node;
217
+ if (tooltipEnabled) triggerProps.ref(node);
218
+ },
219
+ id: controlId,
220
+ "data-cy": dataCy != null ? dataCy : "select-button",
221
+ onKeyDown: handleKeyDown,
222
+ fullWidth,
223
+ variant,
224
+ onClick: (e) => {
225
+ resetActiveToSelected();
226
+ toggle(e);
227
+ },
228
+ size,
229
+ style: minWidth != null ? { minWidth } : void 0,
230
+ type: "button",
231
+ "data-forminput": true,
232
+ "aria-haspopup": "listbox",
233
+ "aria-expanded": !!isOpen,
234
+ "aria-controls": listboxId,
235
+ "aria-invalid": Boolean(error) || void 0,
236
+ "aria-describedby": describedBy,
237
+ className: modified ? styles.triggerModified : void 0,
238
+ children: /* @__PURE__ */ jsxs(
239
+ "span",
240
+ {
241
+ className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs",
242
+ style: { width: "100%" },
243
+ children: [
244
+ /* @__PURE__ */ jsx("span", { children: selected ? selected.label : /* @__PURE__ */ jsx("span", { className: "dbc-muted-text", children: placeholder }) }),
245
+ /* @__PURE__ */ jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [
246
+ onClear && selected && /* @__PURE__ */ jsx(
247
+ ClearButton,
248
+ {
249
+ onClick: onClear,
250
+ variant: variant === "header" ? "header" : "default",
251
+ as: "span",
252
+ revealOnHover: true
253
+ }
254
+ ),
255
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
256
+ ] })
257
+ ]
258
+ }
259
+ )
260
+ }
261
+ ),
262
+ children: /* @__PURE__ */ jsxs(Menu, { onKeyDownCapture: handleKeyDown, role: "listbox", className: styles.menu, children: [
263
+ menuHeader ? /* @__PURE__ */ jsx(Menu.Header, { children: menuHeader }) : null,
264
+ options.map((opt, index) => {
265
+ const isSelected = typeof opt.value === "object" && typeof selectedValue === "object" && datakey ? (selectedValue == null ? void 0 : selectedValue[datakey]) === opt.value[datakey] : opt.value === selectedValue;
266
+ const isActive = index === activeIndex;
267
+ return /* @__PURE__ */ jsx(
268
+ Menu.Item,
269
+ {
270
+ active: isActive,
271
+ selected: isSelected,
272
+ itemRole: "option",
273
+ className: isSelected ? styles.selectedOption : void 0,
274
+ children: /* @__PURE__ */ jsx(
275
+ "button",
276
+ {
277
+ ref: (el) => {
278
+ optionRefs.current[index] = el;
279
+ },
280
+ type: "button",
281
+ tabIndex: isActive ? 0 : -1,
282
+ onClick: () => {
283
+ var _a;
284
+ onChange(opt.value);
285
+ (_a = popoverRef.current) == null ? void 0 : _a.close();
286
+ },
287
+ onFocus: () => setActiveIndex(index),
288
+ style: { display: "flex", alignItems: "center", width: "100%" },
289
+ children: opt.label
290
+ }
291
+ )
213
292
  },
214
- id: controlId,
215
- "data-cy": dataCy != null ? dataCy : "select-button",
216
- onKeyDown: handleKeyDown,
217
- fullWidth,
218
- variant,
219
- onClick: (e) => {
220
- resetActiveToSelected();
221
- toggle(e);
222
- },
223
- size,
224
- style: minWidth != null ? { minWidth } : void 0,
225
- type: "button",
226
- "data-forminput": true,
227
- "aria-haspopup": "listbox",
228
- "aria-expanded": !!isOpen,
229
- "aria-controls": listboxId,
230
- "aria-invalid": Boolean(error) || void 0,
231
- "aria-describedby": describedBy,
232
- className: modified ? styles.triggerModified : void 0,
233
- children: /* @__PURE__ */ jsxs(
234
- "span",
235
- {
236
- className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs",
237
- style: { width: "100%" },
238
- children: [
239
- /* @__PURE__ */ jsx("span", { children: selected ? selected.label : /* @__PURE__ */ jsx("span", { className: "dbc-muted-text", children: placeholder }) }),
240
- /* @__PURE__ */ jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xxs", children: [
241
- onClear && selected && /* @__PURE__ */ jsx(
242
- ClearButton,
243
- {
244
- onClick: onClear,
245
- variant: variant === "header" ? "header" : "default",
246
- as: "span",
247
- revealOnHover: true
248
- }
249
- ),
250
- /* @__PURE__ */ jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
251
- ] })
252
- ]
253
- }
254
- )
255
- }
256
- ),
257
- children: /* @__PURE__ */ jsxs(Menu, { onKeyDownCapture: handleKeyDown, role: "listbox", className: styles.menu, children: [
258
- menuHeader ? /* @__PURE__ */ jsx(Menu.Header, { children: menuHeader }) : null,
259
- options.map((opt, index) => {
260
- const isSelected = typeof opt.value === "object" && typeof selectedValue === "object" && datakey ? (selectedValue == null ? void 0 : selectedValue[datakey]) === opt.value[datakey] : opt.value === selectedValue;
261
- const isActive = index === activeIndex;
262
- return /* @__PURE__ */ jsx(
263
- Menu.Item,
264
- {
265
- active: isActive,
266
- selected: isSelected,
267
- itemRole: "option",
268
- className: isSelected ? styles.selectedOption : void 0,
269
- children: /* @__PURE__ */ jsx(
270
- "button",
271
- {
272
- ref: (el) => {
273
- optionRefs.current[index] = el;
274
- },
275
- type: "button",
276
- tabIndex: isActive ? 0 : -1,
277
- onClick: () => {
278
- var _a;
279
- onChange(opt.value);
280
- (_a = popoverRef.current) == null ? void 0 : _a.close();
281
- },
282
- onFocus: () => setActiveIndex(index),
283
- style: { display: "flex", alignItems: "center", width: "100%" },
284
- children: opt.label
285
- }
286
- )
287
- },
288
- String(opt.value)
289
- );
290
- })
291
- ] })
292
- }
293
- ),
294
- (error || helpText) && /* @__PURE__ */ jsx("span", { id: describedById, style: { display: "none" }, children: error != null ? error : helpText })
295
- ]
293
+ String(opt.value)
294
+ );
295
+ })
296
+ ] })
297
+ }
298
+ )
296
299
  }
297
300
  );
298
301
  }
@@ -6,6 +6,7 @@ var react = require('react');
6
6
  var useTooltipTrigger = require('../../../components/overlay/tooltip/useTooltipTrigger');
7
7
  var styles = require('./Textarea.module.css');
8
8
  var InputContainer = require('../input-container/InputContainer');
9
+ var messageIds = require('../input-container/messageIds');
9
10
 
10
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
12
 
@@ -77,10 +78,11 @@ const Textarea = function Textarea2({
77
78
  value,
78
79
  onChange: onInput,
79
80
  disabled,
80
- "aria-invalid": Boolean(error) || void 0
81
+ "aria-invalid": Boolean(error) || void 0,
82
+ "aria-describedby": messageIds.getDescribedBy(textareaId, { error, helpText }, rest["aria-describedby"])
81
83
  }
82
84
  ),
83
- [rest, textareaId, className, placeholder, rows, value, onInput, disabled, error]
85
+ [rest, textareaId, className, placeholder, rows, value, onInput, disabled, error, helpText]
84
86
  );
85
87
  const tooltipEnabled = Boolean(tooltip) && (showTooltip != null ? showTooltip : true);
86
88
  const { triggerProps } = useTooltipTrigger.useTooltipTrigger({
@@ -4,6 +4,7 @@ import { useId, useRef, useCallback, useLayoutEffect, useMemo } from 'react';
4
4
  import { useTooltipTrigger } from '../../../components/overlay/tooltip/useTooltipTrigger';
5
5
  import styles from './Textarea.module.css';
6
6
  import { InputContainer } from '../input-container/InputContainer';
7
+ import { getDescribedBy } from '../input-container/messageIds';
7
8
 
8
9
  const Textarea = function Textarea2({
9
10
  value,
@@ -71,10 +72,11 @@ const Textarea = function Textarea2({
71
72
  value,
72
73
  onChange: onInput,
73
74
  disabled,
74
- "aria-invalid": Boolean(error) || void 0
75
+ "aria-invalid": Boolean(error) || void 0,
76
+ "aria-describedby": getDescribedBy(textareaId, { error, helpText }, rest["aria-describedby"])
75
77
  }
76
78
  ),
77
- [rest, textareaId, className, placeholder, rows, value, onInput, disabled, error]
79
+ [rest, textareaId, className, placeholder, rows, value, onInput, disabled, error, helpText]
78
80
  );
79
81
  const tooltipEnabled = Boolean(tooltip) && (showTooltip != null ? showTooltip : true);
80
82
  const { triggerProps } = useTooltipTrigger({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbcdk/react-components",
3
- "version": "0.0.201",
3
+ "version": "0.0.203",
4
4
  "description": "Reusable React components for DBC projects",
5
5
  "license": "ISC",
6
6
  "author": "",