@dbcdk/react-components 0.0.211 → 0.0.212
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/README.md +6 -1
- package/dist/components/button/Button.cjs +2 -1
- package/dist/components/button/Button.d.ts +6 -1
- package/dist/components/button/Button.js +2 -1
- package/dist/components/button/Button.module.css +14 -0
- package/dist/components/color-scheme-button/ColorSchemeButton.cjs +2 -2
- package/dist/components/color-scheme-button/ColorSchemeButton.js +2 -2
- package/dist/components/forms/file-upload/FileUpload.cjs +4 -0
- package/dist/components/forms/file-upload/FileUpload.js +4 -0
- package/dist/components/forms/form-select/FormSelect.cjs +4 -0
- package/dist/components/forms/form-select/FormSelect.d.ts +1 -1
- package/dist/components/forms/form-select/FormSelect.js +4 -0
- package/dist/components/forms/input/Input.cjs +4 -0
- package/dist/components/forms/input/Input.js +4 -0
- package/dist/components/forms/radio-buttons/RadioButtonGroup.cjs +6 -5
- package/dist/components/forms/radio-buttons/RadioButtonGroup.js +2 -5
- package/dist/components/forms/radio-buttons/RadioButtons.module.css +15 -0
- package/dist/components/forms/select/Select.cjs +4 -0
- package/dist/components/forms/select/Select.d.ts +1 -1
- package/dist/components/forms/select/Select.js +4 -0
- package/dist/components/forms/text-area/Textarea.cjs +4 -0
- package/dist/components/forms/text-area/Textarea.js +4 -0
- package/dist/components/forms/typeahead/Typeahead.cjs +109 -42
- package/dist/components/forms/typeahead/Typeahead.d.ts +6 -0
- package/dist/components/forms/typeahead/Typeahead.js +109 -42
- package/dist/components/forms/typeahead/Typeahead.module.css +16 -0
- package/dist/components/headline/CollapsibleHeadline.cjs +15 -18
- package/dist/components/headline/CollapsibleHeadline.d.ts +2 -2
- package/dist/components/headline/CollapsibleHeadline.js +15 -18
- package/dist/components/headline/Headline.module.css +22 -0
- package/dist/components/sidebar/components/SidebarItem.cjs +2 -0
- package/dist/components/sidebar/components/SidebarItem.d.ts +2 -1
- package/dist/components/sidebar/components/SidebarItem.js +2 -0
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.cjs +2 -0
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.d.ts +2 -1
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.js +2 -0
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.module.css +1 -1
- package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +40 -0
- package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.cjs +2 -0
- package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.d.ts +2 -1
- package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.js +2 -0
- package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.module.css +9 -0
- package/dist/components/sidebar/components/sidebar-items/SidebarItems.cjs +6 -4
- package/dist/components/sidebar/components/sidebar-items/SidebarItems.js +6 -4
- package/dist/components/theme-script/ThemeScript.cjs +1 -1
- package/dist/components/theme-script/ThemeScript.d.ts +1 -1
- package/dist/components/theme-script/ThemeScript.js +1 -1
- package/dist/hooks/useColorScheme.cjs +1 -1
- package/dist/hooks/useColorScheme.js +1 -1
- package/dist/hooks/useGetActiveTheme.cjs +1 -1
- package/dist/hooks/useGetActiveTheme.js +1 -1
- package/dist/styles/themes/dbc/colors.css +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,6 +100,11 @@ export default function Header() {
|
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
Light is the default color scheme, including before hydration. `ThemeScript`,
|
|
104
|
+
`useColorScheme()`, and the color scheme controls preserve saved Dark or System
|
|
105
|
+
preferences. To default to the OS preference explicitly, use
|
|
106
|
+
`<ThemeScript defaultColorScheme="system" />` and `useColorScheme('system')`.
|
|
107
|
+
|
|
103
108
|
The hook updates `data-product-theme`, applies the selected product theme's
|
|
104
109
|
token overrides, and persists the selection.
|
|
105
110
|
|
|
@@ -150,7 +155,7 @@ elsewhere it's the `storageKey` option passed to `useColorScheme`):
|
|
|
150
155
|
|
|
151
156
|
```tsx
|
|
152
157
|
const { theme, switchTheme } = useTheme({ defaultTheme: 'dbc', storageKey: 'my-app-theme' })
|
|
153
|
-
const { colorScheme, switchColorScheme } = useColorScheme(
|
|
158
|
+
const { colorScheme, switchColorScheme } = useColorScheme(undefined, {
|
|
154
159
|
storageKey: 'my-app-color-scheme',
|
|
155
160
|
})
|
|
156
161
|
```
|
|
@@ -54,7 +54,8 @@ const Button = React__namespace.forwardRef(function Button2({
|
|
|
54
54
|
const computedClassName = cx(
|
|
55
55
|
styles__default.default.button,
|
|
56
56
|
styles__default.default[variant],
|
|
57
|
-
|
|
57
|
+
// A class name can't start with a digit.
|
|
58
|
+
size === "2xs" ? styles__default.default.size2xs : styles__default.default[size],
|
|
58
59
|
fullWidth ? styles__default.default.fullWidth : "",
|
|
59
60
|
active ? styles__default.default.active : "",
|
|
60
61
|
loading ? styles__default.default.loading : "",
|
|
@@ -7,7 +7,12 @@ export type ButtonSize = Exclude<Size, 'xl'>;
|
|
|
7
7
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
8
8
|
variant?: ButtonVariant;
|
|
9
9
|
shape?: 'default' | 'rounded' | 'round';
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* `2xs`: an icon button that fits within a line of text, e.g. next to a form label - no
|
|
12
|
+
* border or padding, so it doesn't make the line taller. Use it with `variant="inline"`
|
|
13
|
+
* and an `aria-label`. Its click target is small, so keep other controls at a distance.
|
|
14
|
+
*/
|
|
15
|
+
size?: ButtonSize | '2xs';
|
|
11
16
|
fullWidth?: boolean;
|
|
12
17
|
icon?: React.ReactNode;
|
|
13
18
|
loading?: boolean;
|
|
@@ -30,7 +30,8 @@ const Button = React.forwardRef(function Button2({
|
|
|
30
30
|
const computedClassName = cx(
|
|
31
31
|
styles.button,
|
|
32
32
|
styles[variant],
|
|
33
|
-
|
|
33
|
+
// A class name can't start with a digit.
|
|
34
|
+
size === "2xs" ? styles.size2xs : styles[size],
|
|
34
35
|
fullWidth ? styles.fullWidth : "",
|
|
35
36
|
active ? styles.active : "",
|
|
36
37
|
loading ? styles.loading : "",
|
|
@@ -292,3 +292,17 @@
|
|
|
292
292
|
inline-size: var(--icon-size-sm);
|
|
293
293
|
block-size: var(--icon-size-sm);
|
|
294
294
|
}
|
|
295
|
+
|
|
296
|
+
/* Fits within a line of text: no border or padding to make the line taller. */
|
|
297
|
+
.button.size2xs {
|
|
298
|
+
height: auto;
|
|
299
|
+
min-block-size: 0;
|
|
300
|
+
padding: 0;
|
|
301
|
+
border-width: 0;
|
|
302
|
+
line-height: 1;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.button.size2xs svg {
|
|
306
|
+
inline-size: var(--icon-size-xs);
|
|
307
|
+
block-size: var(--icon-size-xs);
|
|
308
|
+
}
|
|
@@ -16,7 +16,7 @@ const COLOR_SCHEME_OPTIONS = [
|
|
|
16
16
|
function ColorSchemeMenuSection({
|
|
17
17
|
storageKey
|
|
18
18
|
} = {}) {
|
|
19
|
-
const { colorScheme, switchColorScheme } = useColorScheme.useColorScheme(
|
|
19
|
+
const { colorScheme, switchColorScheme } = useColorScheme.useColorScheme(void 0, { storageKey });
|
|
20
20
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
21
21
|
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Header, { children: "Udseende" }),
|
|
22
22
|
COLOR_SCHEME_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -37,7 +37,7 @@ function ColorSchemeButton({
|
|
|
37
37
|
variant = "outlined",
|
|
38
38
|
storageKey
|
|
39
39
|
}) {
|
|
40
|
-
const { colorScheme, switchColorScheme } = useColorScheme.useColorScheme(
|
|
40
|
+
const { colorScheme, switchColorScheme } = useColorScheme.useColorScheme(void 0, { storageKey });
|
|
41
41
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
42
42
|
Popover.Popover,
|
|
43
43
|
{
|
|
@@ -14,7 +14,7 @@ const COLOR_SCHEME_OPTIONS = [
|
|
|
14
14
|
function ColorSchemeMenuSection({
|
|
15
15
|
storageKey
|
|
16
16
|
} = {}) {
|
|
17
|
-
const { colorScheme, switchColorScheme } = useColorScheme(
|
|
17
|
+
const { colorScheme, switchColorScheme } = useColorScheme(void 0, { storageKey });
|
|
18
18
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19
19
|
/* @__PURE__ */ jsx(Menu.Header, { children: "Udseende" }),
|
|
20
20
|
COLOR_SCHEME_OPTIONS.map((option) => /* @__PURE__ */ jsx(
|
|
@@ -35,7 +35,7 @@ function ColorSchemeButton({
|
|
|
35
35
|
variant = "outlined",
|
|
36
36
|
storageKey
|
|
37
37
|
}) {
|
|
38
|
-
const { colorScheme, switchColorScheme } = useColorScheme(
|
|
38
|
+
const { colorScheme, switchColorScheme } = useColorScheme(void 0, { storageKey });
|
|
39
39
|
return /* @__PURE__ */ jsx(
|
|
40
40
|
Popover,
|
|
41
41
|
{
|
|
@@ -22,6 +22,8 @@ const FileUpload = react.forwardRef(function FileUpload2({
|
|
|
22
22
|
fullWidth = false,
|
|
23
23
|
required,
|
|
24
24
|
modified,
|
|
25
|
+
modifiedLabel,
|
|
26
|
+
labelAlignment,
|
|
25
27
|
onChange,
|
|
26
28
|
children,
|
|
27
29
|
hint,
|
|
@@ -78,6 +80,8 @@ const FileUpload = react.forwardRef(function FileUpload2({
|
|
|
78
80
|
fullWidth,
|
|
79
81
|
required,
|
|
80
82
|
modified,
|
|
83
|
+
modifiedLabel,
|
|
84
|
+
labelAlignment,
|
|
81
85
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
82
86
|
"label",
|
|
83
87
|
{
|
|
@@ -16,6 +16,8 @@ const FileUpload = forwardRef(function FileUpload2({
|
|
|
16
16
|
fullWidth = false,
|
|
17
17
|
required,
|
|
18
18
|
modified,
|
|
19
|
+
modifiedLabel,
|
|
20
|
+
labelAlignment,
|
|
19
21
|
onChange,
|
|
20
22
|
children,
|
|
21
23
|
hint,
|
|
@@ -72,6 +74,8 @@ const FileUpload = forwardRef(function FileUpload2({
|
|
|
72
74
|
fullWidth,
|
|
73
75
|
required,
|
|
74
76
|
modified,
|
|
77
|
+
modifiedLabel,
|
|
78
|
+
labelAlignment,
|
|
75
79
|
children: /* @__PURE__ */ jsxs(
|
|
76
80
|
"label",
|
|
77
81
|
{
|
|
@@ -67,6 +67,8 @@ function FormSelect({
|
|
|
67
67
|
tooltip,
|
|
68
68
|
tooltipPlacement = "right",
|
|
69
69
|
modified = false,
|
|
70
|
+
modifiedLabel,
|
|
71
|
+
labelAlignment,
|
|
70
72
|
// FormSelect props
|
|
71
73
|
id,
|
|
72
74
|
name,
|
|
@@ -130,6 +132,8 @@ function FormSelect({
|
|
|
130
132
|
labelWidth,
|
|
131
133
|
required,
|
|
132
134
|
modified,
|
|
135
|
+
modifiedLabel,
|
|
136
|
+
labelAlignment,
|
|
133
137
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
134
138
|
"div",
|
|
135
139
|
{
|
|
@@ -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, 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;
|
|
34
|
+
export declare function FormSelect<T extends string | number | Record<string, any>>({ label, labelAction, error, helpText, helpTextAddition, orientation, labelWidth, fullWidth, required, tooltip, tooltipPlacement, modified, modifiedLabel, labelAlignment, id, name, options, selectedValue, onChange, placeholder, size, variant, onClear, datakey, dataCy, disabled, includePlaceholderOption, allowClearWhenRequired, }: FormSelectProps<T>): React.ReactNode;
|
|
35
35
|
export {};
|
|
@@ -42,6 +42,8 @@ function FormSelect({
|
|
|
42
42
|
tooltip,
|
|
43
43
|
tooltipPlacement = "right",
|
|
44
44
|
modified = false,
|
|
45
|
+
modifiedLabel,
|
|
46
|
+
labelAlignment,
|
|
45
47
|
// FormSelect props
|
|
46
48
|
id,
|
|
47
49
|
name,
|
|
@@ -105,6 +107,8 @@ function FormSelect({
|
|
|
105
107
|
labelWidth,
|
|
106
108
|
required,
|
|
107
109
|
modified,
|
|
110
|
+
modifiedLabel,
|
|
111
|
+
labelAlignment,
|
|
108
112
|
children: /* @__PURE__ */ jsxs(
|
|
109
113
|
"div",
|
|
110
114
|
{
|
|
@@ -36,6 +36,8 @@ const Input = react.forwardRef(function Input2({
|
|
|
36
36
|
tooltip,
|
|
37
37
|
tooltipPlacement = "right",
|
|
38
38
|
modified = false,
|
|
39
|
+
modifiedLabel,
|
|
40
|
+
labelAlignment,
|
|
39
41
|
icon,
|
|
40
42
|
autoFocus,
|
|
41
43
|
minWidth,
|
|
@@ -104,6 +106,8 @@ const Input = react.forwardRef(function Input2({
|
|
|
104
106
|
labelWidth,
|
|
105
107
|
required,
|
|
106
108
|
modified,
|
|
109
|
+
modifiedLabel,
|
|
110
|
+
labelAlignment,
|
|
107
111
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
108
112
|
"div",
|
|
109
113
|
{
|
|
@@ -30,6 +30,8 @@ const Input = forwardRef(function Input2({
|
|
|
30
30
|
tooltip,
|
|
31
31
|
tooltipPlacement = "right",
|
|
32
32
|
modified = false,
|
|
33
|
+
modifiedLabel,
|
|
34
|
+
labelAlignment,
|
|
33
35
|
icon,
|
|
34
36
|
autoFocus,
|
|
35
37
|
minWidth,
|
|
@@ -98,6 +100,8 @@ const Input = forwardRef(function Input2({
|
|
|
98
100
|
labelWidth,
|
|
99
101
|
required,
|
|
100
102
|
modified,
|
|
103
|
+
modifiedLabel,
|
|
104
|
+
labelAlignment,
|
|
101
105
|
children: /* @__PURE__ */ jsxs(
|
|
102
106
|
"div",
|
|
103
107
|
{
|
|
@@ -4,8 +4,13 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var RadioButton = require('./RadioButton');
|
|
7
|
+
var styles = require('./RadioButtons.module.css');
|
|
7
8
|
var InputContainer = require('../input-container/InputContainer');
|
|
8
9
|
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
13
|
+
|
|
9
14
|
function RadioButtonGroup({
|
|
10
15
|
name,
|
|
11
16
|
value,
|
|
@@ -31,11 +36,7 @@ function RadioButtonGroup({
|
|
|
31
36
|
role: "radiogroup",
|
|
32
37
|
"aria-invalid": Boolean(error) || void 0,
|
|
33
38
|
"data-cy": dataCy,
|
|
34
|
-
|
|
35
|
-
display: "flex",
|
|
36
|
-
flexDirection: direction,
|
|
37
|
-
gap: "8px"
|
|
38
|
-
},
|
|
39
|
+
className: [styles__default.default.group, direction === "row" ? styles__default.default.groupRow : void 0].filter(Boolean).join(" "),
|
|
39
40
|
children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
40
41
|
RadioButton.RadioButton,
|
|
41
42
|
{
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useId } from 'react';
|
|
4
4
|
import { RadioButton } from './RadioButton';
|
|
5
|
+
import styles from './RadioButtons.module.css';
|
|
5
6
|
import { InputContainer } from '../input-container/InputContainer';
|
|
6
7
|
|
|
7
8
|
function RadioButtonGroup({
|
|
@@ -29,11 +30,7 @@ function RadioButtonGroup({
|
|
|
29
30
|
role: "radiogroup",
|
|
30
31
|
"aria-invalid": Boolean(error) || void 0,
|
|
31
32
|
"data-cy": dataCy,
|
|
32
|
-
|
|
33
|
-
display: "flex",
|
|
34
|
-
flexDirection: direction,
|
|
35
|
-
gap: "8px"
|
|
36
|
-
},
|
|
33
|
+
className: [styles.group, direction === "row" ? styles.groupRow : void 0].filter(Boolean).join(" "),
|
|
37
34
|
children: options.map((opt) => /* @__PURE__ */ jsx(
|
|
38
35
|
RadioButton,
|
|
39
36
|
{
|
|
@@ -129,3 +129,18 @@
|
|
|
129
129
|
width: 12px;
|
|
130
130
|
height: 12px;
|
|
131
131
|
}
|
|
132
|
+
|
|
133
|
+
.group {
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-direction: column;
|
|
136
|
+
gap: var(--spacing-sm);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.groupRow {
|
|
140
|
+
flex-direction: row;
|
|
141
|
+
flex-wrap: wrap;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.groupRow > * {
|
|
145
|
+
flex-shrink: 0;
|
|
146
|
+
}
|
|
@@ -29,6 +29,8 @@ function Select({
|
|
|
29
29
|
tooltip,
|
|
30
30
|
tooltipPlacement = "right",
|
|
31
31
|
modified = false,
|
|
32
|
+
modifiedLabel,
|
|
33
|
+
labelAlignment,
|
|
32
34
|
id,
|
|
33
35
|
options,
|
|
34
36
|
selectedValue,
|
|
@@ -199,6 +201,8 @@ function Select({
|
|
|
199
201
|
labelWidth,
|
|
200
202
|
required,
|
|
201
203
|
modified,
|
|
204
|
+
modifiedLabel,
|
|
205
|
+
labelAlignment,
|
|
202
206
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
203
207
|
Popover.Popover,
|
|
204
208
|
{
|
|
@@ -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, 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;
|
|
23
|
+
export declare function Select<T extends string | number | Record<string, any>>({ label, labelAction, error, helpText, helpTextAddition, orientation, labelWidth, fullWidth, required, tooltip, tooltipPlacement, modified, modifiedLabel, labelAlignment, id, options, selectedValue, onChange, placeholder, size, variant, onClear, datakey, dataCy, disabled, minWidth, menuHeader, }: SelectProps<T>): React.ReactNode;
|
|
24
24
|
export {};
|
|
@@ -23,6 +23,8 @@ function Select({
|
|
|
23
23
|
tooltip,
|
|
24
24
|
tooltipPlacement = "right",
|
|
25
25
|
modified = false,
|
|
26
|
+
modifiedLabel,
|
|
27
|
+
labelAlignment,
|
|
26
28
|
id,
|
|
27
29
|
options,
|
|
28
30
|
selectedValue,
|
|
@@ -193,6 +195,8 @@ function Select({
|
|
|
193
195
|
labelWidth,
|
|
194
196
|
required,
|
|
195
197
|
modified,
|
|
198
|
+
modifiedLabel,
|
|
199
|
+
labelAlignment,
|
|
196
200
|
children: /* @__PURE__ */ jsx(
|
|
197
201
|
Popover,
|
|
198
202
|
{
|
|
@@ -26,6 +26,8 @@ const Textarea = function Textarea2({
|
|
|
26
26
|
adjustHeight,
|
|
27
27
|
id,
|
|
28
28
|
modified = false,
|
|
29
|
+
modifiedLabel,
|
|
30
|
+
labelAlignment,
|
|
29
31
|
// InputContainer props
|
|
30
32
|
label,
|
|
31
33
|
error,
|
|
@@ -97,6 +99,8 @@ const Textarea = function Textarea2({
|
|
|
97
99
|
InputContainer.InputContainer,
|
|
98
100
|
{
|
|
99
101
|
modified,
|
|
102
|
+
modifiedLabel,
|
|
103
|
+
labelAlignment,
|
|
100
104
|
label,
|
|
101
105
|
htmlFor: textareaId,
|
|
102
106
|
error,
|
|
@@ -20,6 +20,8 @@ const Textarea = function Textarea2({
|
|
|
20
20
|
adjustHeight,
|
|
21
21
|
id,
|
|
22
22
|
modified = false,
|
|
23
|
+
modifiedLabel,
|
|
24
|
+
labelAlignment,
|
|
23
25
|
// InputContainer props
|
|
24
26
|
label,
|
|
25
27
|
error,
|
|
@@ -91,6 +93,8 @@ const Textarea = function Textarea2({
|
|
|
91
93
|
InputContainer,
|
|
92
94
|
{
|
|
93
95
|
modified,
|
|
96
|
+
modifiedLabel,
|
|
97
|
+
labelAlignment,
|
|
94
98
|
label,
|
|
95
99
|
htmlFor: textareaId,
|
|
96
100
|
error,
|
|
@@ -32,6 +32,23 @@ function _interopNamespace(e) {
|
|
|
32
32
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
33
33
|
var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
34
34
|
|
|
35
|
+
function orderByGroup(options) {
|
|
36
|
+
if (!options.some((option) => option.group)) return options;
|
|
37
|
+
const groups = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const option of options) {
|
|
39
|
+
const group = option.group || void 0;
|
|
40
|
+
const entries = groups.get(group);
|
|
41
|
+
if (entries) entries.push(option);
|
|
42
|
+
else groups.set(group, [option]);
|
|
43
|
+
}
|
|
44
|
+
return Array.from(groups.values()).flat();
|
|
45
|
+
}
|
|
46
|
+
function findEnabledIndex(items, start, step) {
|
|
47
|
+
for (let index = start; index >= 0 && index < items.length; index += step) {
|
|
48
|
+
if (!items[index].disabled) return index;
|
|
49
|
+
}
|
|
50
|
+
return -1;
|
|
51
|
+
}
|
|
35
52
|
function parseLengthToPx(value, referenceFontSize = 16) {
|
|
36
53
|
if (!value) return 0;
|
|
37
54
|
const trimmed = value.trim();
|
|
@@ -197,16 +214,25 @@ function Typeahead({
|
|
|
197
214
|
filteredOptions = options;
|
|
198
215
|
} else {
|
|
199
216
|
filteredOptions = options.filter(
|
|
200
|
-
(option) =>
|
|
217
|
+
(option) => {
|
|
218
|
+
var _a2, _b, _c, _d;
|
|
219
|
+
return option.label.toLocaleLowerCase().includes(normalizedQuery) || ((_b = (_a2 = option.description) == null ? void 0 : _a2.toLocaleLowerCase().includes(normalizedQuery)) != null ? _b : false) || ((_d = (_c = option.group) == null ? void 0 : _c.toLocaleLowerCase().includes(normalizedQuery)) != null ? _d : false);
|
|
220
|
+
}
|
|
201
221
|
);
|
|
202
222
|
}
|
|
203
223
|
}
|
|
224
|
+
filteredOptions = orderByGroup(filteredOptions);
|
|
204
225
|
if (typeof maxVisibleOptions === "number" && Number.isFinite(maxVisibleOptions)) {
|
|
205
226
|
filteredOptions = filteredOptions.slice(0, Math.max(0, maxVisibleOptions));
|
|
206
227
|
}
|
|
228
|
+
const groupStarts = /* @__PURE__ */ new Map();
|
|
229
|
+
filteredOptions.forEach((option, index) => {
|
|
230
|
+
if (option.group && !groupStarts.has(option.group)) groupStarts.set(option.group, index);
|
|
231
|
+
});
|
|
207
232
|
const commitSelection = React__namespace.useCallback(
|
|
208
233
|
(option) => {
|
|
209
234
|
var _a2, _b;
|
|
235
|
+
if (option == null ? void 0 : option.disabled) return;
|
|
210
236
|
locallyClearedRef.current = false;
|
|
211
237
|
setHideSelectedHighlight(false);
|
|
212
238
|
if (mode === "multi") {
|
|
@@ -334,24 +360,21 @@ function Typeahead({
|
|
|
334
360
|
}, [selectedOption, selectedSingleText, mode]);
|
|
335
361
|
const getSelectedIndex = React__namespace.useCallback(
|
|
336
362
|
(items) => {
|
|
337
|
-
|
|
338
|
-
if (locallyClearedRef.current) return
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
const singleSelectedIndex = items.findIndex((option) => option.value === selectedValue);
|
|
345
|
-
return singleSelectedIndex >= 0 ? singleSelectedIndex : 0;
|
|
363
|
+
const firstEnabled = findEnabledIndex(items, 0, 1);
|
|
364
|
+
if (firstEnabled < 0 || locallyClearedRef.current) return firstEnabled;
|
|
365
|
+
const selectedIndex = items.findIndex(
|
|
366
|
+
(option) => !option.disabled && (mode === "multi" ? Array.isArray(selectedValue) && selectedValue.includes(option.value) : option.value === selectedValue)
|
|
367
|
+
);
|
|
368
|
+
return selectedIndex >= 0 ? selectedIndex : firstEnabled;
|
|
346
369
|
},
|
|
347
370
|
[mode, selectedValue]
|
|
348
371
|
);
|
|
349
372
|
React.useEffect(() => {
|
|
350
373
|
setActiveIndex((current) => {
|
|
351
|
-
if (
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
return
|
|
374
|
+
if (locallyClearedRef.current || current < 0 || !filteredOptions[current] || filteredOptions[current].disabled) {
|
|
375
|
+
return getSelectedIndex(filteredOptions);
|
|
376
|
+
}
|
|
377
|
+
return current;
|
|
355
378
|
});
|
|
356
379
|
}, [filteredOptions, getSelectedIndex]);
|
|
357
380
|
React.useEffect(() => {
|
|
@@ -452,7 +475,14 @@ function Typeahead({
|
|
|
452
475
|
}
|
|
453
476
|
const exactLabelMatch = options.find((option) => option.label === inputValue);
|
|
454
477
|
if (exactLabelMatch) {
|
|
455
|
-
|
|
478
|
+
if (exactLabelMatch.disabled) {
|
|
479
|
+
setInputValue(selectedSingleText);
|
|
480
|
+
setQuery("");
|
|
481
|
+
setOpen(false);
|
|
482
|
+
setActiveIndex(-1);
|
|
483
|
+
} else {
|
|
484
|
+
commitSelection(exactLabelMatch);
|
|
485
|
+
}
|
|
456
486
|
return;
|
|
457
487
|
}
|
|
458
488
|
if (allowCustomValue) {
|
|
@@ -484,7 +514,7 @@ function Typeahead({
|
|
|
484
514
|
if (justClearedRef.current) return;
|
|
485
515
|
setQuery("");
|
|
486
516
|
setOpen(true);
|
|
487
|
-
setActiveIndex(getSelectedIndex(options));
|
|
517
|
+
setActiveIndex(getSelectedIndex(orderByGroup(options)));
|
|
488
518
|
}, [getSelectedIndex, options]);
|
|
489
519
|
const openWithCurrentFilter = React__namespace.useCallback(() => {
|
|
490
520
|
if (justClearedRef.current) return;
|
|
@@ -526,7 +556,7 @@ function Typeahead({
|
|
|
526
556
|
if (isAlreadyFocused && mode === "single" && selectedOption && !locallyClearedRef.current) {
|
|
527
557
|
prepareSingleSearchInput();
|
|
528
558
|
setOpen(true);
|
|
529
|
-
setActiveIndex(getSelectedIndex(options));
|
|
559
|
+
setActiveIndex(getSelectedIndex(orderByGroup(options)));
|
|
530
560
|
} else if (isAlreadyFocused && !open) {
|
|
531
561
|
setOpen(true);
|
|
532
562
|
setActiveIndex(getSelectedIndex(filteredOptions));
|
|
@@ -573,7 +603,8 @@ function Typeahead({
|
|
|
573
603
|
setActiveIndex((index) => {
|
|
574
604
|
if (filteredOptions.length === 0) return -1;
|
|
575
605
|
if (index < 0) return getSelectedIndex(filteredOptions);
|
|
576
|
-
|
|
606
|
+
const next = findEnabledIndex(filteredOptions, index + 1, 1);
|
|
607
|
+
return next >= 0 ? next : index;
|
|
577
608
|
});
|
|
578
609
|
return;
|
|
579
610
|
case "ArrowUp":
|
|
@@ -583,20 +614,23 @@ function Typeahead({
|
|
|
583
614
|
return;
|
|
584
615
|
}
|
|
585
616
|
setActiveIndex((index) => {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
617
|
+
const next = findEnabledIndex(
|
|
618
|
+
filteredOptions,
|
|
619
|
+
index < 0 ? filteredOptions.length - 1 : index - 1,
|
|
620
|
+
-1
|
|
621
|
+
);
|
|
622
|
+
return next >= 0 ? next : index;
|
|
589
623
|
});
|
|
590
624
|
return;
|
|
591
625
|
case "Home":
|
|
592
626
|
if (!open || filteredOptions.length === 0) return;
|
|
593
627
|
e.preventDefault();
|
|
594
|
-
setActiveIndex(0);
|
|
628
|
+
setActiveIndex(findEnabledIndex(filteredOptions, 0, 1));
|
|
595
629
|
return;
|
|
596
630
|
case "End":
|
|
597
631
|
if (!open || filteredOptions.length === 0) return;
|
|
598
632
|
e.preventDefault();
|
|
599
|
-
setActiveIndex(filteredOptions.length - 1);
|
|
633
|
+
setActiveIndex(findEnabledIndex(filteredOptions, filteredOptions.length - 1, -1));
|
|
600
634
|
return;
|
|
601
635
|
case "Enter":
|
|
602
636
|
if (!open) return;
|
|
@@ -650,7 +684,7 @@ function Typeahead({
|
|
|
650
684
|
if (nextOpen) {
|
|
651
685
|
if (mode === "single" && selectedOption && !locallyClearedRef.current) {
|
|
652
686
|
setQuery("");
|
|
653
|
-
setActiveIndex(getSelectedIndex(options));
|
|
687
|
+
setActiveIndex(getSelectedIndex(orderByGroup(options)));
|
|
654
688
|
} else {
|
|
655
689
|
setActiveIndex(getSelectedIndex(filteredOptions));
|
|
656
690
|
}
|
|
@@ -768,41 +802,74 @@ function Typeahead({
|
|
|
768
802
|
const isActive = index === activeIndex;
|
|
769
803
|
const isSelected = mode === "multi" ? Array.isArray(selectedValue) && selectedValue.includes(option.value) : option.value === selectedValue && !hideSelectedHighlight;
|
|
770
804
|
const optionId = `${listboxId}-option-${index}`;
|
|
771
|
-
|
|
805
|
+
const groupId = option.group ? `${listboxId}-group-${groupStarts.get(option.group)}` : void 0;
|
|
806
|
+
const startsGroup = !!option.group && groupStarts.get(option.group) === index;
|
|
807
|
+
const descriptionId = option.description ? `${optionId}-description` : void 0;
|
|
808
|
+
const describedBy = [groupId, descriptionId].filter(Boolean).join(" ") || void 0;
|
|
809
|
+
const labelContent = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.optionText, children: [
|
|
810
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label }),
|
|
811
|
+
option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { id: descriptionId, className: styles__default.default.description, children: option.description })
|
|
812
|
+
] });
|
|
813
|
+
const item = mode === "multi" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
772
814
|
Menu.Menu.CheckItem,
|
|
773
815
|
{
|
|
774
816
|
checked: isSelected,
|
|
817
|
+
disabled: option.disabled,
|
|
775
818
|
active: isActive,
|
|
776
819
|
interactiveProps: {
|
|
777
820
|
id: optionId,
|
|
778
821
|
role: "option",
|
|
779
|
-
|
|
822
|
+
"aria-describedby": describedBy,
|
|
823
|
+
"aria-label": option.label,
|
|
824
|
+
"aria-disabled": option.disabled || void 0,
|
|
825
|
+
onMouseEnter: () => {
|
|
826
|
+
if (!option.disabled) setActiveIndex(index);
|
|
827
|
+
},
|
|
780
828
|
onMouseDown: (e) => {
|
|
781
829
|
interactingWithOptionsRef.current = true;
|
|
782
830
|
e.preventDefault();
|
|
783
831
|
},
|
|
784
832
|
onKeyDown: (e) => handleTabKeyDown(e)
|
|
785
833
|
},
|
|
786
|
-
label:
|
|
834
|
+
label: labelContent,
|
|
787
835
|
onCheckedChange: () => commitSelection(option)
|
|
788
836
|
},
|
|
789
837
|
option.value
|
|
790
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
791
|
-
|
|
838
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
839
|
+
Menu.Menu.Item,
|
|
792
840
|
{
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
841
|
+
active: isActive,
|
|
842
|
+
selected: isSelected,
|
|
843
|
+
disabled: option.disabled,
|
|
844
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
845
|
+
"button",
|
|
846
|
+
{
|
|
847
|
+
id: optionId,
|
|
848
|
+
type: "button",
|
|
849
|
+
role: "option",
|
|
850
|
+
"aria-selected": isSelected,
|
|
851
|
+
"aria-describedby": describedBy,
|
|
852
|
+
"aria-label": option.label,
|
|
853
|
+
"aria-disabled": option.disabled || void 0,
|
|
854
|
+
disabled: option.disabled,
|
|
855
|
+
onMouseEnter: () => {
|
|
856
|
+
if (!option.disabled) setActiveIndex(index);
|
|
857
|
+
},
|
|
858
|
+
onMouseDown: (e) => {
|
|
859
|
+
e.preventDefault();
|
|
860
|
+
},
|
|
861
|
+
onKeyDown: (e) => handleTabKeyDown(e),
|
|
862
|
+
onClick: () => commitSelection(option),
|
|
863
|
+
children: labelContent
|
|
864
|
+
}
|
|
865
|
+
)
|
|
866
|
+
},
|
|
867
|
+
option.value
|
|
868
|
+
);
|
|
869
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
|
870
|
+
startsGroup && /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Header, { id: groupId, children: option.group }),
|
|
871
|
+
item
|
|
872
|
+
] }, option.value);
|
|
806
873
|
}) : /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { disabled: true, children: emptyMessage }) })
|
|
807
874
|
}
|
|
808
875
|
),
|
|
@@ -3,6 +3,12 @@ import { InputProps, InputVariant } from '../../../components/forms/input/Input'
|
|
|
3
3
|
type TypeaheadOption<T> = {
|
|
4
4
|
label: string;
|
|
5
5
|
value: T;
|
|
6
|
+
/** Optional section header; groups follow their first occurrence in the list. */
|
|
7
|
+
group?: string;
|
|
8
|
+
/** Secondary option text, included in default search but not the selected input value. */
|
|
9
|
+
description?: string;
|
|
10
|
+
/** Visible but unavailable for selection by pointer, keyboard, or exact-label commit. */
|
|
11
|
+
disabled?: boolean;
|
|
6
12
|
};
|
|
7
13
|
type MultiValueDisplayMode = 'chips' | 'count';
|
|
8
14
|
type MultiSelectedValuesDisplayMode = 'hidden' | 'below-input';
|