@dbcdk/react-components 0.0.200 → 0.0.201
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/dist/components/alert/Alert.cjs +31 -3
- package/dist/components/alert/Alert.d.ts +11 -1
- package/dist/components/alert/Alert.js +31 -3
- package/dist/components/alert/Alert.module.css +26 -10
- package/dist/components/button/Button.cjs +38 -29
- package/dist/components/button/Button.js +39 -29
- package/dist/components/forms/checkbox/Checkbox.cjs +3 -0
- package/dist/components/forms/checkbox/Checkbox.d.ts +8 -1
- package/dist/components/forms/checkbox/Checkbox.js +3 -0
- package/dist/components/forms/checkbox/Checkbox.module.css +2 -1
- package/dist/components/forms/form-select/FormSelect.cjs +2 -0
- package/dist/components/forms/form-select/FormSelect.d.ts +1 -1
- package/dist/components/forms/form-select/FormSelect.js +2 -0
- package/dist/components/forms/input-container/InputContainer.cjs +1 -1
- package/dist/components/forms/input-container/InputContainer.js +1 -1
- package/dist/components/forms/select/Select.cjs +29 -18
- package/dist/components/forms/select/Select.d.ts +1 -1
- package/dist/components/forms/select/Select.js +29 -18
- package/dist/components/popover/Popover.cjs +1 -0
- package/dist/components/popover/Popover.js +1 -0
- package/package.json +1 -1
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var lucideReact = require('lucide-react');
|
|
5
6
|
var styles = require('./Alert.module.css');
|
|
7
|
+
var Button = require('../button/Button');
|
|
6
8
|
var Headline = require('../headline/Headline');
|
|
7
9
|
var Icon = require('../icon/Icon');
|
|
8
10
|
|
|
@@ -14,12 +16,16 @@ function Alert({
|
|
|
14
16
|
children,
|
|
15
17
|
title,
|
|
16
18
|
headlineSize = 3,
|
|
19
|
+
headlineWeight = 600,
|
|
20
|
+
headlineVariant,
|
|
17
21
|
severity = "neutral",
|
|
18
22
|
customIcon,
|
|
19
23
|
disableIcon = false,
|
|
20
24
|
fullWidth = false,
|
|
21
25
|
maxWidth = "72ch",
|
|
22
|
-
role = "status"
|
|
26
|
+
role = "status",
|
|
27
|
+
onClose,
|
|
28
|
+
closeLabel = "Luk"
|
|
23
29
|
}) {
|
|
24
30
|
const hasLeading = Boolean(customIcon) || !disableIcon;
|
|
25
31
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -40,10 +46,32 @@ function Alert({
|
|
|
40
46
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.content, children: [
|
|
41
47
|
title ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.titleRow, children: [
|
|
42
48
|
hasLeading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.leading, children: customIcon != null ? customIcon : /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { severity }) }) : null,
|
|
43
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.title, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.title, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
50
|
+
Headline.Headline,
|
|
51
|
+
{
|
|
52
|
+
size: headlineSize,
|
|
53
|
+
weight: headlineWeight,
|
|
54
|
+
variant: headlineVariant,
|
|
55
|
+
disableMargin: true,
|
|
56
|
+
children: title
|
|
57
|
+
}
|
|
58
|
+
) })
|
|
44
59
|
] }) : null,
|
|
45
60
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.body, children })
|
|
46
|
-
] })
|
|
61
|
+
] }),
|
|
62
|
+
onClose ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
63
|
+
Button.Button,
|
|
64
|
+
{
|
|
65
|
+
type: "button",
|
|
66
|
+
variant: "inline",
|
|
67
|
+
shape: "round",
|
|
68
|
+
size: "sm",
|
|
69
|
+
className: styles__default.default.closeButton,
|
|
70
|
+
"aria-label": closeLabel,
|
|
71
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, {}),
|
|
72
|
+
onClick: onClose
|
|
73
|
+
}
|
|
74
|
+
) : null
|
|
47
75
|
]
|
|
48
76
|
}
|
|
49
77
|
);
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import type { JSX, ReactNode } from 'react';
|
|
2
2
|
import type { Severity } from '../../constants/severity.types';
|
|
3
|
+
import { type HeadlineProps } from '../headline/Headline';
|
|
3
4
|
export interface AlertProps {
|
|
4
5
|
children: ReactNode;
|
|
5
6
|
title?: ReactNode;
|
|
6
7
|
headlineSize?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
8
|
+
headlineWeight?: HeadlineProps['weight'];
|
|
9
|
+
headlineVariant?: HeadlineProps['variant'];
|
|
7
10
|
severity?: Severity;
|
|
8
11
|
customIcon?: ReactNode;
|
|
9
12
|
disableIcon?: boolean;
|
|
10
13
|
fullWidth?: boolean;
|
|
11
14
|
maxWidth?: string | number;
|
|
12
15
|
role?: 'status' | 'alert';
|
|
16
|
+
/**
|
|
17
|
+
* Shows a close button that calls this. The alert has no open state of its
|
|
18
|
+
* own: the parent decides whether to keep rendering it.
|
|
19
|
+
*/
|
|
20
|
+
onClose?: () => void;
|
|
21
|
+
/** Accessible name for the close button. */
|
|
22
|
+
closeLabel?: string;
|
|
13
23
|
}
|
|
14
|
-
export declare function Alert({ children, title, headlineSize, severity, customIcon, disableIcon, fullWidth, maxWidth, role, }: AlertProps): JSX.Element;
|
|
24
|
+
export declare function Alert({ children, title, headlineSize, headlineWeight, headlineVariant, severity, customIcon, disableIcon, fullWidth, maxWidth, role, onClose, closeLabel, }: AlertProps): JSX.Element;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { X } from 'lucide-react';
|
|
3
4
|
import styles from './Alert.module.css';
|
|
5
|
+
import { Button } from '../button/Button';
|
|
4
6
|
import { Headline } from '../headline/Headline';
|
|
5
7
|
import { Icon } from '../icon/Icon';
|
|
6
8
|
|
|
@@ -8,12 +10,16 @@ function Alert({
|
|
|
8
10
|
children,
|
|
9
11
|
title,
|
|
10
12
|
headlineSize = 3,
|
|
13
|
+
headlineWeight = 600,
|
|
14
|
+
headlineVariant,
|
|
11
15
|
severity = "neutral",
|
|
12
16
|
customIcon,
|
|
13
17
|
disableIcon = false,
|
|
14
18
|
fullWidth = false,
|
|
15
19
|
maxWidth = "72ch",
|
|
16
|
-
role = "status"
|
|
20
|
+
role = "status",
|
|
21
|
+
onClose,
|
|
22
|
+
closeLabel = "Luk"
|
|
17
23
|
}) {
|
|
18
24
|
const hasLeading = Boolean(customIcon) || !disableIcon;
|
|
19
25
|
return /* @__PURE__ */ jsxs(
|
|
@@ -34,10 +40,32 @@ function Alert({
|
|
|
34
40
|
/* @__PURE__ */ jsxs("div", { className: styles.content, children: [
|
|
35
41
|
title ? /* @__PURE__ */ jsxs("div", { className: styles.titleRow, children: [
|
|
36
42
|
hasLeading ? /* @__PURE__ */ jsx("div", { className: styles.leading, children: customIcon != null ? customIcon : /* @__PURE__ */ jsx(Icon, { severity }) }) : null,
|
|
37
|
-
/* @__PURE__ */ jsx("div", { className: styles.title, children: /* @__PURE__ */ jsx(
|
|
43
|
+
/* @__PURE__ */ jsx("div", { className: styles.title, children: /* @__PURE__ */ jsx(
|
|
44
|
+
Headline,
|
|
45
|
+
{
|
|
46
|
+
size: headlineSize,
|
|
47
|
+
weight: headlineWeight,
|
|
48
|
+
variant: headlineVariant,
|
|
49
|
+
disableMargin: true,
|
|
50
|
+
children: title
|
|
51
|
+
}
|
|
52
|
+
) })
|
|
38
53
|
] }) : null,
|
|
39
54
|
/* @__PURE__ */ jsx("div", { className: styles.body, children })
|
|
40
|
-
] })
|
|
55
|
+
] }),
|
|
56
|
+
onClose ? /* @__PURE__ */ jsx(
|
|
57
|
+
Button,
|
|
58
|
+
{
|
|
59
|
+
type: "button",
|
|
60
|
+
variant: "inline",
|
|
61
|
+
shape: "round",
|
|
62
|
+
size: "sm",
|
|
63
|
+
className: styles.closeButton,
|
|
64
|
+
"aria-label": closeLabel,
|
|
65
|
+
icon: /* @__PURE__ */ jsx(X, {}),
|
|
66
|
+
onClick: onClose
|
|
67
|
+
}
|
|
68
|
+
) : null
|
|
41
69
|
]
|
|
42
70
|
}
|
|
43
71
|
);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
.container {
|
|
2
2
|
--alert-bg: var(--color-bg-toolbar);
|
|
3
3
|
--alert-fg: var(--color-fg-default);
|
|
4
|
-
--alert-border: var(--color-border-subtle);
|
|
5
4
|
|
|
6
5
|
display: flex;
|
|
7
6
|
align-items: flex-start;
|
|
@@ -9,10 +8,11 @@
|
|
|
9
8
|
inline-size: min(100%, var(--alert-max-width, 72ch));
|
|
10
9
|
max-inline-size: 100%;
|
|
11
10
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
12
|
-
border: 1px solid var(--alert-border);
|
|
13
11
|
border-radius: var(--border-radius-default);
|
|
14
12
|
background: var(--alert-bg);
|
|
15
13
|
color: var(--alert-fg);
|
|
14
|
+
/* Severity stripe on the left edge. An inset shadow keeps size and padding unchanged. */
|
|
15
|
+
box-shadow: inset var(--border-width-thick) 0 0 var(--alert-accent, transparent);
|
|
16
16
|
box-sizing: border-box;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
.content {
|
|
43
43
|
display: flex;
|
|
44
44
|
flex-direction: column;
|
|
45
|
-
gap: var(--spacing-
|
|
45
|
+
gap: var(--spacing-sm);
|
|
46
46
|
min-width: 0;
|
|
47
47
|
flex: 1 1 auto;
|
|
48
48
|
}
|
|
@@ -59,44 +59,60 @@
|
|
|
59
59
|
font-size: var(--font-size-sm);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
.closeButton {
|
|
63
|
+
flex: 0 0 auto;
|
|
64
|
+
margin-inline-start: auto;
|
|
65
|
+
align-self: flex-start;
|
|
66
|
+
}
|
|
67
|
+
|
|
62
68
|
.neutral {
|
|
63
69
|
--alert-bg: var(--color-bg-toolbar);
|
|
64
70
|
--alert-fg: var(--color-fg-default);
|
|
65
|
-
--alert-border: var(--color-border-subtle);
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
.success {
|
|
69
74
|
--alert-bg: var(--color-status-success-bg);
|
|
70
75
|
--alert-fg: var(--color-status-success-fg);
|
|
71
|
-
--alert-
|
|
76
|
+
--alert-accent: var(--color-status-success);
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
.warning {
|
|
75
80
|
--alert-bg: var(--color-status-warning-bg);
|
|
76
81
|
--alert-fg: var(--color-status-warning-fg);
|
|
77
|
-
--alert-
|
|
82
|
+
--alert-accent: var(--color-status-warning);
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
.error {
|
|
81
86
|
--alert-bg: var(--color-status-error-bg);
|
|
82
87
|
--alert-fg: var(--color-status-error-fg);
|
|
83
|
-
--alert-
|
|
88
|
+
--alert-accent: var(--color-status-error);
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
.info {
|
|
87
92
|
--alert-bg: var(--color-status-info-bg);
|
|
88
93
|
--alert-fg: var(--color-status-info-fg);
|
|
89
|
-
--alert-
|
|
94
|
+
--alert-accent: var(--color-status-info);
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
.brand {
|
|
93
98
|
--alert-bg: color-mix(in srgb, var(--color-brand) 10%, var(--color-bg-surface));
|
|
94
99
|
--alert-fg: var(--color-brand);
|
|
95
|
-
--alert-
|
|
100
|
+
--alert-accent: var(--color-brand);
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
.accent {
|
|
99
104
|
--alert-bg: var(--color-accent-bg);
|
|
100
105
|
--alert-fg: var(--color-accent-fg);
|
|
101
|
-
--alert-
|
|
106
|
+
--alert-accent: var(--color-accent);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Square corners on the striped edge, so the stripe stays straight. */
|
|
110
|
+
.success,
|
|
111
|
+
.warning,
|
|
112
|
+
.error,
|
|
113
|
+
.info,
|
|
114
|
+
.brand,
|
|
115
|
+
.accent {
|
|
116
|
+
border-top-left-radius: 0;
|
|
117
|
+
border-bottom-left-radius: 0;
|
|
102
118
|
}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var lucideReact = require('lucide-react');
|
|
6
5
|
var React = require('react');
|
|
6
|
+
var lucideReact = require('lucide-react');
|
|
7
7
|
var useTooltipTrigger = require('../../components/overlay/tooltip/useTooltipTrigger');
|
|
8
|
+
var refs_utils = require('../../utils/refs.utils');
|
|
8
9
|
var styles = require('./Button.module.css');
|
|
9
10
|
|
|
10
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -33,15 +34,6 @@ var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
|
33
34
|
function cx(...parts) {
|
|
34
35
|
return parts.filter(Boolean).join(" ");
|
|
35
36
|
}
|
|
36
|
-
function mergeRefs(...refs) {
|
|
37
|
-
return (node) => {
|
|
38
|
-
for (const ref of refs) {
|
|
39
|
-
if (!ref) continue;
|
|
40
|
-
if (typeof ref === "function") ref(node);
|
|
41
|
-
else ref.current = node;
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
37
|
const Button = React__namespace.forwardRef(function Button2({
|
|
46
38
|
variant = "outlined",
|
|
47
39
|
shape = "default",
|
|
@@ -58,7 +50,6 @@ const Button = React__namespace.forwardRef(function Button2({
|
|
|
58
50
|
type = "button",
|
|
59
51
|
...rest
|
|
60
52
|
}, ref) {
|
|
61
|
-
var _a;
|
|
62
53
|
const { className: userClassName, ...buttonProps } = rest;
|
|
63
54
|
const computedClassName = cx(
|
|
64
55
|
styles__default.default.button,
|
|
@@ -71,17 +62,26 @@ const Button = React__namespace.forwardRef(function Button2({
|
|
|
71
62
|
userClassName
|
|
72
63
|
);
|
|
73
64
|
const tooltipEnabled = Boolean(tooltip);
|
|
74
|
-
const
|
|
75
|
-
const
|
|
65
|
+
const linkChild = isLink && React__namespace.isValidElement(children) ? children : null;
|
|
66
|
+
const childRef = linkChild == null ? void 0 : linkChild.props.ref;
|
|
76
67
|
const { triggerProps, id: tooltipId } = useTooltipTrigger.useTooltipTrigger({
|
|
77
68
|
content: tooltipEnabled ? tooltip : null,
|
|
78
69
|
placement: tooltipPlacement,
|
|
79
70
|
offset: 8
|
|
80
71
|
});
|
|
81
|
-
const { ref: hoverRef,
|
|
72
|
+
const { ref: hoverRef, ...tooltipTriggerProps } = triggerProps;
|
|
73
|
+
const { onPointerEnter: hoverEnter, onPointerLeave: hoverLeave } = tooltipTriggerProps;
|
|
74
|
+
const isDisabled = Boolean(buttonProps.disabled);
|
|
75
|
+
const tooltipOnControl = tooltipEnabled && (Boolean(linkChild) || !isDisabled);
|
|
76
|
+
const tooltipRef = tooltipOnControl ? hoverRef : void 0;
|
|
77
|
+
const mergedRef = React__namespace.useMemo(
|
|
78
|
+
() => refs_utils.mergeRefs(childRef, ref, tooltipRef),
|
|
79
|
+
[childRef, ref, tooltipRef]
|
|
80
|
+
);
|
|
82
81
|
const describedBy = (() => {
|
|
83
82
|
const existing = typeof buttonProps["aria-describedby"] === "string" ? buttonProps["aria-describedby"] : "";
|
|
84
83
|
const ids = [existing, tooltipEnabled ? tooltipId : ""].filter(Boolean);
|
|
84
|
+
if (linkChild == null ? void 0 : linkChild.props["aria-describedby"]) ids.unshift(linkChild.props["aria-describedby"]);
|
|
85
85
|
return ids.length ? ids.join(" ") : void 0;
|
|
86
86
|
})();
|
|
87
87
|
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -90,39 +90,48 @@ const Button = React__namespace.forwardRef(function Button2({
|
|
|
90
90
|
loading && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "flex", opacity: 0.5 }, className: "spin", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LoaderCircle, {}) })
|
|
91
91
|
] });
|
|
92
92
|
let buttonEl;
|
|
93
|
-
if (
|
|
94
|
-
const
|
|
93
|
+
if (linkChild) {
|
|
94
|
+
const Link = linkChild.type;
|
|
95
|
+
const childClassName = typeof linkChild.props.className === "string" ? linkChild.props.className : "";
|
|
95
96
|
const { disabled, onClick, ...linkButtonProps } = buttonProps;
|
|
96
97
|
const handleClick = (e) => {
|
|
98
|
+
var _a, _b;
|
|
97
99
|
if (disabled) {
|
|
98
100
|
e.preventDefault();
|
|
99
101
|
return;
|
|
100
102
|
}
|
|
103
|
+
(_b = (_a = linkChild.props).onClick) == null ? void 0 : _b.call(_a, e);
|
|
104
|
+
if (e.defaultPrevented) return;
|
|
101
105
|
onClick == null ? void 0 : onClick(e);
|
|
102
106
|
};
|
|
103
|
-
buttonEl =
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
buttonEl = /* @__PURE__ */ React.createElement(
|
|
108
|
+
Link,
|
|
109
|
+
{
|
|
110
|
+
...linkChild.props,
|
|
111
|
+
...linkButtonProps,
|
|
112
|
+
...tooltipEnabled ? tooltipTriggerProps : {},
|
|
113
|
+
key: linkChild.key,
|
|
114
|
+
ref: mergedRef,
|
|
115
|
+
className: cx(childClassName, computedClassName, styles__default.default.buttonLink),
|
|
116
|
+
"aria-describedby": describedBy,
|
|
117
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
118
|
+
onClick: handleClick
|
|
119
|
+
},
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
112
121
|
icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx(styles__default.default.icon, spinIcon ? "spin" : ""), children: icon }),
|
|
113
|
-
|
|
122
|
+
linkChild.props.children,
|
|
114
123
|
loading && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "flex", opacity: 0.5 }, className: "spin", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LoaderCircle, {}) })
|
|
115
124
|
] })
|
|
116
|
-
|
|
125
|
+
);
|
|
117
126
|
} else {
|
|
118
|
-
const isDisabled = Boolean(buttonProps.disabled);
|
|
119
127
|
buttonEl = /* @__PURE__ */ jsxRuntime.jsx(
|
|
120
128
|
"button",
|
|
121
129
|
{
|
|
130
|
+
ref: mergedRef,
|
|
122
131
|
className: computedClassName,
|
|
123
132
|
type,
|
|
124
133
|
...buttonProps,
|
|
125
|
-
...
|
|
134
|
+
...tooltipOnControl ? tooltipTriggerProps : {},
|
|
126
135
|
"aria-describedby": describedBy,
|
|
127
136
|
children: content
|
|
128
137
|
}
|
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { LoaderCircle } from 'lucide-react';
|
|
4
3
|
import * as React from 'react';
|
|
4
|
+
import { createElement } from 'react';
|
|
5
|
+
import { LoaderCircle } from 'lucide-react';
|
|
5
6
|
import { useTooltipTrigger } from '../../components/overlay/tooltip/useTooltipTrigger';
|
|
7
|
+
import { mergeRefs } from '../../utils/refs.utils';
|
|
6
8
|
import styles from './Button.module.css';
|
|
7
9
|
|
|
8
10
|
function cx(...parts) {
|
|
9
11
|
return parts.filter(Boolean).join(" ");
|
|
10
12
|
}
|
|
11
|
-
function mergeRefs(...refs) {
|
|
12
|
-
return (node) => {
|
|
13
|
-
for (const ref of refs) {
|
|
14
|
-
if (!ref) continue;
|
|
15
|
-
if (typeof ref === "function") ref(node);
|
|
16
|
-
else ref.current = node;
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
13
|
const Button = React.forwardRef(function Button2({
|
|
21
14
|
variant = "outlined",
|
|
22
15
|
shape = "default",
|
|
@@ -33,7 +26,6 @@ const Button = React.forwardRef(function Button2({
|
|
|
33
26
|
type = "button",
|
|
34
27
|
...rest
|
|
35
28
|
}, ref) {
|
|
36
|
-
var _a;
|
|
37
29
|
const { className: userClassName, ...buttonProps } = rest;
|
|
38
30
|
const computedClassName = cx(
|
|
39
31
|
styles.button,
|
|
@@ -46,17 +38,26 @@ const Button = React.forwardRef(function Button2({
|
|
|
46
38
|
userClassName
|
|
47
39
|
);
|
|
48
40
|
const tooltipEnabled = Boolean(tooltip);
|
|
49
|
-
const
|
|
50
|
-
const
|
|
41
|
+
const linkChild = isLink && React.isValidElement(children) ? children : null;
|
|
42
|
+
const childRef = linkChild == null ? void 0 : linkChild.props.ref;
|
|
51
43
|
const { triggerProps, id: tooltipId } = useTooltipTrigger({
|
|
52
44
|
content: tooltipEnabled ? tooltip : null,
|
|
53
45
|
placement: tooltipPlacement,
|
|
54
46
|
offset: 8
|
|
55
47
|
});
|
|
56
|
-
const { ref: hoverRef,
|
|
48
|
+
const { ref: hoverRef, ...tooltipTriggerProps } = triggerProps;
|
|
49
|
+
const { onPointerEnter: hoverEnter, onPointerLeave: hoverLeave } = tooltipTriggerProps;
|
|
50
|
+
const isDisabled = Boolean(buttonProps.disabled);
|
|
51
|
+
const tooltipOnControl = tooltipEnabled && (Boolean(linkChild) || !isDisabled);
|
|
52
|
+
const tooltipRef = tooltipOnControl ? hoverRef : void 0;
|
|
53
|
+
const mergedRef = React.useMemo(
|
|
54
|
+
() => mergeRefs(childRef, ref, tooltipRef),
|
|
55
|
+
[childRef, ref, tooltipRef]
|
|
56
|
+
);
|
|
57
57
|
const describedBy = (() => {
|
|
58
58
|
const existing = typeof buttonProps["aria-describedby"] === "string" ? buttonProps["aria-describedby"] : "";
|
|
59
59
|
const ids = [existing, tooltipEnabled ? tooltipId : ""].filter(Boolean);
|
|
60
|
+
if (linkChild == null ? void 0 : linkChild.props["aria-describedby"]) ids.unshift(linkChild.props["aria-describedby"]);
|
|
60
61
|
return ids.length ? ids.join(" ") : void 0;
|
|
61
62
|
})();
|
|
62
63
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -65,39 +66,48 @@ const Button = React.forwardRef(function Button2({
|
|
|
65
66
|
loading && /* @__PURE__ */ jsx("span", { style: { display: "flex", opacity: 0.5 }, className: "spin", children: /* @__PURE__ */ jsx(LoaderCircle, {}) })
|
|
66
67
|
] });
|
|
67
68
|
let buttonEl;
|
|
68
|
-
if (
|
|
69
|
-
const
|
|
69
|
+
if (linkChild) {
|
|
70
|
+
const Link = linkChild.type;
|
|
71
|
+
const childClassName = typeof linkChild.props.className === "string" ? linkChild.props.className : "";
|
|
70
72
|
const { disabled, onClick, ...linkButtonProps } = buttonProps;
|
|
71
73
|
const handleClick = (e) => {
|
|
74
|
+
var _a, _b;
|
|
72
75
|
if (disabled) {
|
|
73
76
|
e.preventDefault();
|
|
74
77
|
return;
|
|
75
78
|
}
|
|
79
|
+
(_b = (_a = linkChild.props).onClick) == null ? void 0 : _b.call(_a, e);
|
|
80
|
+
if (e.defaultPrevented) return;
|
|
76
81
|
onClick == null ? void 0 : onClick(e);
|
|
77
82
|
};
|
|
78
|
-
buttonEl =
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
buttonEl = /* @__PURE__ */ createElement(
|
|
84
|
+
Link,
|
|
85
|
+
{
|
|
86
|
+
...linkChild.props,
|
|
87
|
+
...linkButtonProps,
|
|
88
|
+
...tooltipEnabled ? tooltipTriggerProps : {},
|
|
89
|
+
key: linkChild.key,
|
|
90
|
+
ref: mergedRef,
|
|
91
|
+
className: cx(childClassName, computedClassName, styles.buttonLink),
|
|
92
|
+
"aria-describedby": describedBy,
|
|
93
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
94
|
+
onClick: handleClick
|
|
95
|
+
},
|
|
96
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
87
97
|
icon && /* @__PURE__ */ jsx("span", { className: cx(styles.icon, spinIcon ? "spin" : ""), children: icon }),
|
|
88
|
-
|
|
98
|
+
linkChild.props.children,
|
|
89
99
|
loading && /* @__PURE__ */ jsx("span", { style: { display: "flex", opacity: 0.5 }, className: "spin", children: /* @__PURE__ */ jsx(LoaderCircle, {}) })
|
|
90
100
|
] })
|
|
91
|
-
|
|
101
|
+
);
|
|
92
102
|
} else {
|
|
93
|
-
const isDisabled = Boolean(buttonProps.disabled);
|
|
94
103
|
buttonEl = /* @__PURE__ */ jsx(
|
|
95
104
|
"button",
|
|
96
105
|
{
|
|
106
|
+
ref: mergedRef,
|
|
97
107
|
className: computedClassName,
|
|
98
108
|
type,
|
|
99
109
|
...buttonProps,
|
|
100
|
-
...
|
|
110
|
+
...tooltipOnControl ? tooltipTriggerProps : {},
|
|
101
111
|
"aria-describedby": describedBy,
|
|
102
112
|
children: content
|
|
103
113
|
}
|
|
@@ -21,6 +21,7 @@ function Checkbox({
|
|
|
21
21
|
labelAs = "label",
|
|
22
22
|
endAdornment,
|
|
23
23
|
endAdornmentAriaHidden = true,
|
|
24
|
+
labelAction,
|
|
24
25
|
size = "md",
|
|
25
26
|
modified,
|
|
26
27
|
containerLabel,
|
|
@@ -78,6 +79,7 @@ function Checkbox({
|
|
|
78
79
|
}
|
|
79
80
|
) }),
|
|
80
81
|
label && (labelAs === "label" ? /* @__PURE__ */ jsxRuntime.jsx("label", { className: styles__default.default.label, htmlFor: controlId, children: label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.label, children: label })),
|
|
82
|
+
labelAction && !containerLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.labelAction, "data-checkbox-label-action": "true", children: labelAction }),
|
|
81
83
|
endAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
82
84
|
]
|
|
83
85
|
}
|
|
@@ -88,6 +90,7 @@ function Checkbox({
|
|
|
88
90
|
{
|
|
89
91
|
modified,
|
|
90
92
|
label: containerLabel,
|
|
93
|
+
labelAction: containerLabel ? labelAction : void 0,
|
|
91
94
|
htmlFor: controlId,
|
|
92
95
|
error,
|
|
93
96
|
helpText,
|
|
@@ -21,6 +21,13 @@ interface CheckboxProps {
|
|
|
21
21
|
* Defaults to true since endAdornment is typically decorative.
|
|
22
22
|
*/
|
|
23
23
|
endAdornmentAriaHidden?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Content next to the label, e.g. a help button or other additional content.
|
|
26
|
+
* Rendered next to `containerLabel` when set, otherwise after the per-item
|
|
27
|
+
* `label`.
|
|
28
|
+
* Unlike `endAdornment`, it is never hidden from assistive tech.
|
|
29
|
+
*/
|
|
30
|
+
labelAction?: ReactNode;
|
|
24
31
|
size?: Size;
|
|
25
32
|
containerLabel?: string;
|
|
26
33
|
error?: string;
|
|
@@ -35,5 +42,5 @@ interface CheckboxProps {
|
|
|
35
42
|
tooltip?: ReactNode;
|
|
36
43
|
tooltipPlacement?: TooltipPlacement;
|
|
37
44
|
}
|
|
38
|
-
export declare function Checkbox({ checked: controlled, onChange, variant, disabled, label, labelAs, endAdornment, endAdornmentAriaHidden, size, modified, containerLabel, error, helpText, orientation, labelWidth, fullWidth, required, noContainer, id, 'data-cy': dataCy, tooltip, tooltipPlacement, }: CheckboxProps): JSX.Element;
|
|
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;
|
|
39
46
|
export {};
|
|
@@ -15,6 +15,7 @@ function Checkbox({
|
|
|
15
15
|
labelAs = "label",
|
|
16
16
|
endAdornment,
|
|
17
17
|
endAdornmentAriaHidden = true,
|
|
18
|
+
labelAction,
|
|
18
19
|
size = "md",
|
|
19
20
|
modified,
|
|
20
21
|
containerLabel,
|
|
@@ -72,6 +73,7 @@ function Checkbox({
|
|
|
72
73
|
}
|
|
73
74
|
) }),
|
|
74
75
|
label && (labelAs === "label" ? /* @__PURE__ */ jsx("label", { className: styles.label, htmlFor: controlId, children: label }) : /* @__PURE__ */ jsx("span", { className: styles.label, children: label })),
|
|
76
|
+
labelAction && !containerLabel && /* @__PURE__ */ jsx("span", { className: styles.labelAction, "data-checkbox-label-action": "true", children: labelAction }),
|
|
75
77
|
endAdornment && /* @__PURE__ */ jsx("span", { className: styles.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
76
78
|
]
|
|
77
79
|
}
|
|
@@ -82,6 +84,7 @@ function Checkbox({
|
|
|
82
84
|
{
|
|
83
85
|
modified,
|
|
84
86
|
label: containerLabel,
|
|
87
|
+
labelAction: containerLabel ? labelAction : void 0,
|
|
85
88
|
htmlFor: controlId,
|
|
86
89
|
error,
|
|
87
90
|
helpText,
|
|
@@ -55,6 +55,7 @@ function findSelectedOption(options, selectedValue, datakey) {
|
|
|
55
55
|
function FormSelect({
|
|
56
56
|
// InputContainer props
|
|
57
57
|
label,
|
|
58
|
+
labelAction,
|
|
58
59
|
error,
|
|
59
60
|
helpText,
|
|
60
61
|
orientation = "vertical",
|
|
@@ -119,6 +120,7 @@ function FormSelect({
|
|
|
119
120
|
InputContainer.InputContainer,
|
|
120
121
|
{
|
|
121
122
|
label,
|
|
123
|
+
labelAction,
|
|
122
124
|
htmlFor: controlId,
|
|
123
125
|
fullWidth,
|
|
124
126
|
error,
|
|
@@ -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, 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, 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 {};
|
|
@@ -30,6 +30,7 @@ function findSelectedOption(options, selectedValue, datakey) {
|
|
|
30
30
|
function FormSelect({
|
|
31
31
|
// InputContainer props
|
|
32
32
|
label,
|
|
33
|
+
labelAction,
|
|
33
34
|
error,
|
|
34
35
|
helpText,
|
|
35
36
|
orientation = "vertical",
|
|
@@ -94,6 +95,7 @@ function FormSelect({
|
|
|
94
95
|
InputContainer,
|
|
95
96
|
{
|
|
96
97
|
label,
|
|
98
|
+
labelAction,
|
|
97
99
|
htmlFor: controlId,
|
|
98
100
|
fullWidth,
|
|
99
101
|
error,
|
|
@@ -24,7 +24,7 @@ function InputContainer({
|
|
|
24
24
|
labelAlignment = "center",
|
|
25
25
|
modified = false
|
|
26
26
|
}) {
|
|
27
|
-
const renderLabelRow = (label || labelAction) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.labelRow} dbc-flex dbc-items-center dbc-gap-
|
|
27
|
+
const renderLabelRow = (label || labelAction) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.labelRow} dbc-flex dbc-items-center dbc-gap-xs`, children: [
|
|
28
28
|
label && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: styles__default.default.label, htmlFor, children: [
|
|
29
29
|
label,
|
|
30
30
|
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.required, children: " *" })
|
|
@@ -18,7 +18,7 @@ function InputContainer({
|
|
|
18
18
|
labelAlignment = "center",
|
|
19
19
|
modified = false
|
|
20
20
|
}) {
|
|
21
|
-
const renderLabelRow = (label || labelAction) && /* @__PURE__ */ jsxs("div", { className: `${styles.labelRow} dbc-flex dbc-items-center dbc-gap-
|
|
21
|
+
const renderLabelRow = (label || labelAction) && /* @__PURE__ */ jsxs("div", { className: `${styles.labelRow} dbc-flex dbc-items-center dbc-gap-xs`, children: [
|
|
22
22
|
label && /* @__PURE__ */ jsxs("label", { className: styles.label, htmlFor, children: [
|
|
23
23
|
label,
|
|
24
24
|
required && /* @__PURE__ */ jsx("span", { className: styles.required, children: " *" })
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var lucideReact = require('lucide-react');
|
|
6
5
|
var react = require('react');
|
|
7
6
|
var useTooltipTrigger = require('../../../components/overlay/tooltip/useTooltipTrigger');
|
|
8
7
|
var styles = require('./Select.module.css');
|
|
@@ -18,6 +17,7 @@ var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
|
18
17
|
|
|
19
18
|
function Select({
|
|
20
19
|
label,
|
|
20
|
+
labelAction,
|
|
21
21
|
error,
|
|
22
22
|
helpText,
|
|
23
23
|
orientation = "vertical",
|
|
@@ -46,6 +46,7 @@ function Select({
|
|
|
46
46
|
const describedById = `${controlId}-desc`;
|
|
47
47
|
const listboxId = `${controlId}-listbox`;
|
|
48
48
|
const popoverRef = react.useRef(null);
|
|
49
|
+
const triggerRef = react.useRef(null);
|
|
49
50
|
const optionRefs = react.useRef([]);
|
|
50
51
|
const typeaheadRef = react.useRef("");
|
|
51
52
|
const typeaheadTimeoutRef = react.useRef(null);
|
|
@@ -61,9 +62,10 @@ function Select({
|
|
|
61
62
|
};
|
|
62
63
|
}, []);
|
|
63
64
|
react.useEffect(() => {
|
|
64
|
-
var _a;
|
|
65
|
+
var _a, _b, _c;
|
|
65
66
|
if (!open) return;
|
|
66
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
69
|
}, [activeIndex, open]);
|
|
68
70
|
const resetActiveToSelected = () => setActiveIndex(selectedIndex >= 0 ? selectedIndex : 0);
|
|
69
71
|
const findTypeaheadMatch = (query, startIndex) => {
|
|
@@ -99,25 +101,30 @@ function Select({
|
|
|
99
101
|
if (!open) setOpen(true);
|
|
100
102
|
};
|
|
101
103
|
const handleKeyDown = (e) => {
|
|
102
|
-
var _a, _b;
|
|
104
|
+
var _a, _b, _c, _d, _e;
|
|
103
105
|
if (e.key.length === 1 && !e.altKey && !e.ctrlKey && !e.metaKey && !/\s/.test(e.key)) {
|
|
104
106
|
e.preventDefault();
|
|
105
107
|
handleTypeahead(e.key);
|
|
106
108
|
return;
|
|
107
109
|
}
|
|
108
110
|
switch (e.key) {
|
|
109
|
-
case "ArrowDown":
|
|
110
|
-
e.preventDefault();
|
|
111
|
-
if (!open) {
|
|
112
|
-
setOpen(true);
|
|
113
|
-
}
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
111
|
+
case "ArrowDown":
|
|
116
112
|
case "ArrowUp": {
|
|
117
113
|
e.preventDefault();
|
|
114
|
+
e.stopPropagation();
|
|
118
115
|
if (!open) {
|
|
116
|
+
resetActiveToSelected();
|
|
119
117
|
setOpen(true);
|
|
118
|
+
break;
|
|
120
119
|
}
|
|
120
|
+
if (options.length === 0) break;
|
|
121
|
+
const nextIndex = Math.max(
|
|
122
|
+
0,
|
|
123
|
+
Math.min(activeIndex + (e.key === "ArrowDown" ? 1 : -1), options.length - 1)
|
|
124
|
+
);
|
|
125
|
+
setActiveIndex(nextIndex);
|
|
126
|
+
(_a = optionRefs.current[nextIndex]) == null ? void 0 : _a.focus();
|
|
127
|
+
(_c = (_b = optionRefs.current[nextIndex]) == null ? void 0 : _b.scrollIntoView) == null ? void 0 : _c.call(_b, { block: "nearest" });
|
|
121
128
|
break;
|
|
122
129
|
}
|
|
123
130
|
case "Enter":
|
|
@@ -129,20 +136,21 @@ function Select({
|
|
|
129
136
|
typeaheadTimeoutRef.current = null;
|
|
130
137
|
}
|
|
131
138
|
if (!open) {
|
|
139
|
+
resetActiveToSelected();
|
|
132
140
|
setOpen(true);
|
|
133
141
|
return;
|
|
134
142
|
}
|
|
135
143
|
const opt = options[activeIndex];
|
|
136
144
|
if (opt) {
|
|
137
145
|
onChange(opt.value);
|
|
138
|
-
(
|
|
146
|
+
(_d = popoverRef.current) == null ? void 0 : _d.close();
|
|
139
147
|
}
|
|
140
148
|
break;
|
|
141
149
|
}
|
|
142
150
|
case "Escape": {
|
|
143
151
|
if (!open) return;
|
|
144
152
|
e.preventDefault();
|
|
145
|
-
(
|
|
153
|
+
(_e = popoverRef.current) == null ? void 0 : _e.close();
|
|
146
154
|
break;
|
|
147
155
|
}
|
|
148
156
|
case "Home": {
|
|
@@ -176,6 +184,7 @@ function Select({
|
|
|
176
184
|
InputContainer.InputContainer,
|
|
177
185
|
{
|
|
178
186
|
label,
|
|
187
|
+
labelAction,
|
|
179
188
|
htmlFor: controlId,
|
|
180
189
|
fullWidth,
|
|
181
190
|
error,
|
|
@@ -189,6 +198,7 @@ function Select({
|
|
|
189
198
|
Popover.Popover,
|
|
190
199
|
{
|
|
191
200
|
ref: popoverRef,
|
|
201
|
+
anchorRef: triggerRef,
|
|
192
202
|
open,
|
|
193
203
|
fullWidth,
|
|
194
204
|
onOpenChange: (next) => {
|
|
@@ -203,6 +213,10 @@ function Select({
|
|
|
203
213
|
{
|
|
204
214
|
disabled,
|
|
205
215
|
...tooltipEnabled ? triggerProps : {},
|
|
216
|
+
ref: (node) => {
|
|
217
|
+
triggerRef.current = node;
|
|
218
|
+
if (tooltipEnabled) triggerProps.ref(node);
|
|
219
|
+
},
|
|
206
220
|
id: controlId,
|
|
207
221
|
"data-cy": dataCy != null ? dataCy : "select-button",
|
|
208
222
|
onKeyDown: handleKeyDown,
|
|
@@ -246,7 +260,7 @@ function Select({
|
|
|
246
260
|
)
|
|
247
261
|
}
|
|
248
262
|
),
|
|
249
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, {
|
|
263
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, { onKeyDownCapture: handleKeyDown, role: "listbox", className: styles__default.default.menu, children: [
|
|
250
264
|
menuHeader ? /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Header, { children: menuHeader }) : null,
|
|
251
265
|
options.map((opt, index) => {
|
|
252
266
|
const isSelected = typeof opt.value === "object" && typeof selectedValue === "object" && datakey ? (selectedValue == null ? void 0 : selectedValue[datakey]) === opt.value[datakey] : opt.value === selectedValue;
|
|
@@ -258,7 +272,7 @@ function Select({
|
|
|
258
272
|
selected: isSelected,
|
|
259
273
|
itemRole: "option",
|
|
260
274
|
className: isSelected ? styles__default.default.selectedOption : void 0,
|
|
261
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
275
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
262
276
|
"button",
|
|
263
277
|
{
|
|
264
278
|
ref: (el) => {
|
|
@@ -273,10 +287,7 @@ function Select({
|
|
|
273
287
|
},
|
|
274
288
|
onFocus: () => setActiveIndex(index),
|
|
275
289
|
style: { display: "flex", alignItems: "center", width: "100%" },
|
|
276
|
-
children:
|
|
277
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { width: 16, display: "inline-flex", justifyContent: "center" }, children: isSelected ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, {}) : null }),
|
|
278
|
-
opt.label
|
|
279
|
-
]
|
|
290
|
+
children: opt.label
|
|
280
291
|
}
|
|
281
292
|
)
|
|
282
293
|
},
|
|
@@ -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, 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, 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,6 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { Check } from 'lucide-react';
|
|
4
3
|
import { useId, useRef, useMemo, useState, useEffect } from 'react';
|
|
5
4
|
import { useTooltipTrigger } from '../../../components/overlay/tooltip/useTooltipTrigger';
|
|
6
5
|
import styles from './Select.module.css';
|
|
@@ -12,6 +11,7 @@ import { InputContainer } from '../input-container/InputContainer';
|
|
|
12
11
|
|
|
13
12
|
function Select({
|
|
14
13
|
label,
|
|
14
|
+
labelAction,
|
|
15
15
|
error,
|
|
16
16
|
helpText,
|
|
17
17
|
orientation = "vertical",
|
|
@@ -40,6 +40,7 @@ function Select({
|
|
|
40
40
|
const describedById = `${controlId}-desc`;
|
|
41
41
|
const listboxId = `${controlId}-listbox`;
|
|
42
42
|
const popoverRef = useRef(null);
|
|
43
|
+
const triggerRef = useRef(null);
|
|
43
44
|
const optionRefs = useRef([]);
|
|
44
45
|
const typeaheadRef = useRef("");
|
|
45
46
|
const typeaheadTimeoutRef = useRef(null);
|
|
@@ -55,9 +56,10 @@ function Select({
|
|
|
55
56
|
};
|
|
56
57
|
}, []);
|
|
57
58
|
useEffect(() => {
|
|
58
|
-
var _a;
|
|
59
|
+
var _a, _b, _c;
|
|
59
60
|
if (!open) return;
|
|
60
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
63
|
}, [activeIndex, open]);
|
|
62
64
|
const resetActiveToSelected = () => setActiveIndex(selectedIndex >= 0 ? selectedIndex : 0);
|
|
63
65
|
const findTypeaheadMatch = (query, startIndex) => {
|
|
@@ -93,25 +95,30 @@ function Select({
|
|
|
93
95
|
if (!open) setOpen(true);
|
|
94
96
|
};
|
|
95
97
|
const handleKeyDown = (e) => {
|
|
96
|
-
var _a, _b;
|
|
98
|
+
var _a, _b, _c, _d, _e;
|
|
97
99
|
if (e.key.length === 1 && !e.altKey && !e.ctrlKey && !e.metaKey && !/\s/.test(e.key)) {
|
|
98
100
|
e.preventDefault();
|
|
99
101
|
handleTypeahead(e.key);
|
|
100
102
|
return;
|
|
101
103
|
}
|
|
102
104
|
switch (e.key) {
|
|
103
|
-
case "ArrowDown":
|
|
104
|
-
e.preventDefault();
|
|
105
|
-
if (!open) {
|
|
106
|
-
setOpen(true);
|
|
107
|
-
}
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
105
|
+
case "ArrowDown":
|
|
110
106
|
case "ArrowUp": {
|
|
111
107
|
e.preventDefault();
|
|
108
|
+
e.stopPropagation();
|
|
112
109
|
if (!open) {
|
|
110
|
+
resetActiveToSelected();
|
|
113
111
|
setOpen(true);
|
|
112
|
+
break;
|
|
114
113
|
}
|
|
114
|
+
if (options.length === 0) break;
|
|
115
|
+
const nextIndex = Math.max(
|
|
116
|
+
0,
|
|
117
|
+
Math.min(activeIndex + (e.key === "ArrowDown" ? 1 : -1), options.length - 1)
|
|
118
|
+
);
|
|
119
|
+
setActiveIndex(nextIndex);
|
|
120
|
+
(_a = optionRefs.current[nextIndex]) == null ? void 0 : _a.focus();
|
|
121
|
+
(_c = (_b = optionRefs.current[nextIndex]) == null ? void 0 : _b.scrollIntoView) == null ? void 0 : _c.call(_b, { block: "nearest" });
|
|
115
122
|
break;
|
|
116
123
|
}
|
|
117
124
|
case "Enter":
|
|
@@ -123,20 +130,21 @@ function Select({
|
|
|
123
130
|
typeaheadTimeoutRef.current = null;
|
|
124
131
|
}
|
|
125
132
|
if (!open) {
|
|
133
|
+
resetActiveToSelected();
|
|
126
134
|
setOpen(true);
|
|
127
135
|
return;
|
|
128
136
|
}
|
|
129
137
|
const opt = options[activeIndex];
|
|
130
138
|
if (opt) {
|
|
131
139
|
onChange(opt.value);
|
|
132
|
-
(
|
|
140
|
+
(_d = popoverRef.current) == null ? void 0 : _d.close();
|
|
133
141
|
}
|
|
134
142
|
break;
|
|
135
143
|
}
|
|
136
144
|
case "Escape": {
|
|
137
145
|
if (!open) return;
|
|
138
146
|
e.preventDefault();
|
|
139
|
-
(
|
|
147
|
+
(_e = popoverRef.current) == null ? void 0 : _e.close();
|
|
140
148
|
break;
|
|
141
149
|
}
|
|
142
150
|
case "Home": {
|
|
@@ -170,6 +178,7 @@ function Select({
|
|
|
170
178
|
InputContainer,
|
|
171
179
|
{
|
|
172
180
|
label,
|
|
181
|
+
labelAction,
|
|
173
182
|
htmlFor: controlId,
|
|
174
183
|
fullWidth,
|
|
175
184
|
error,
|
|
@@ -183,6 +192,7 @@ function Select({
|
|
|
183
192
|
Popover,
|
|
184
193
|
{
|
|
185
194
|
ref: popoverRef,
|
|
195
|
+
anchorRef: triggerRef,
|
|
186
196
|
open,
|
|
187
197
|
fullWidth,
|
|
188
198
|
onOpenChange: (next) => {
|
|
@@ -197,6 +207,10 @@ function Select({
|
|
|
197
207
|
{
|
|
198
208
|
disabled,
|
|
199
209
|
...tooltipEnabled ? triggerProps : {},
|
|
210
|
+
ref: (node) => {
|
|
211
|
+
triggerRef.current = node;
|
|
212
|
+
if (tooltipEnabled) triggerProps.ref(node);
|
|
213
|
+
},
|
|
200
214
|
id: controlId,
|
|
201
215
|
"data-cy": dataCy != null ? dataCy : "select-button",
|
|
202
216
|
onKeyDown: handleKeyDown,
|
|
@@ -240,7 +254,7 @@ function Select({
|
|
|
240
254
|
)
|
|
241
255
|
}
|
|
242
256
|
),
|
|
243
|
-
children: /* @__PURE__ */ jsxs(Menu, {
|
|
257
|
+
children: /* @__PURE__ */ jsxs(Menu, { onKeyDownCapture: handleKeyDown, role: "listbox", className: styles.menu, children: [
|
|
244
258
|
menuHeader ? /* @__PURE__ */ jsx(Menu.Header, { children: menuHeader }) : null,
|
|
245
259
|
options.map((opt, index) => {
|
|
246
260
|
const isSelected = typeof opt.value === "object" && typeof selectedValue === "object" && datakey ? (selectedValue == null ? void 0 : selectedValue[datakey]) === opt.value[datakey] : opt.value === selectedValue;
|
|
@@ -252,7 +266,7 @@ function Select({
|
|
|
252
266
|
selected: isSelected,
|
|
253
267
|
itemRole: "option",
|
|
254
268
|
className: isSelected ? styles.selectedOption : void 0,
|
|
255
|
-
children: /* @__PURE__ */
|
|
269
|
+
children: /* @__PURE__ */ jsx(
|
|
256
270
|
"button",
|
|
257
271
|
{
|
|
258
272
|
ref: (el) => {
|
|
@@ -267,10 +281,7 @@ function Select({
|
|
|
267
281
|
},
|
|
268
282
|
onFocus: () => setActiveIndex(index),
|
|
269
283
|
style: { display: "flex", alignItems: "center", width: "100%" },
|
|
270
|
-
children:
|
|
271
|
-
/* @__PURE__ */ jsx("span", { style: { width: 16, display: "inline-flex", justifyContent: "center" }, children: isSelected ? /* @__PURE__ */ jsx(Check, {}) : null }),
|
|
272
|
-
opt.label
|
|
273
|
-
]
|
|
284
|
+
children: opt.label
|
|
274
285
|
}
|
|
275
286
|
)
|
|
276
287
|
},
|
|
@@ -225,6 +225,7 @@ const Popover = React.forwardRef(function Popover2({
|
|
|
225
225
|
if (!isOpen) return;
|
|
226
226
|
const content = contentRef.current;
|
|
227
227
|
if (!content) return;
|
|
228
|
+
if (anchorRef == null ? void 0 : anchorRef.current) triggerElRef.current = anchorRef.current;
|
|
228
229
|
const triggerEl = (_b = (_a = anchorRef == null ? void 0 : anchorRef.current) != null ? _a : triggerElRef.current) != null ? _b : containerRef.current;
|
|
229
230
|
if (autoFocusContent) {
|
|
230
231
|
const focusables = getFocusable(content);
|
|
@@ -201,6 +201,7 @@ const Popover = forwardRef(function Popover2({
|
|
|
201
201
|
if (!isOpen) return;
|
|
202
202
|
const content = contentRef.current;
|
|
203
203
|
if (!content) return;
|
|
204
|
+
if (anchorRef == null ? void 0 : anchorRef.current) triggerElRef.current = anchorRef.current;
|
|
204
205
|
const triggerEl = (_b = (_a = anchorRef == null ? void 0 : anchorRef.current) != null ? _a : triggerElRef.current) != null ? _b : containerRef.current;
|
|
205
206
|
if (autoFocusContent) {
|
|
206
207
|
const focusables = getFocusable(content);
|