@dbcdk/react-components 0.0.74 → 0.0.76
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/forms/radio-buttons/RadioButtons.module.css +2 -2
- package/dist/components/headline/Headline.module.css +1 -0
- package/dist/components/menu/Menu.d.ts +1 -1
- package/dist/components/menu/Menu.js +19 -2
- package/dist/components/menu/Menu.module.css +13 -7
- package/dist/components/popover/Popover.d.ts +1 -0
- package/dist/components/popover/Popover.js +13 -10
- package/dist/components/popover/Popover.module.css +4 -4
- package/package.json +1 -1
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
justify-content: center;
|
|
32
32
|
|
|
33
33
|
background: var(--color-bg-surface);
|
|
34
|
-
border: 2px solid
|
|
34
|
+
border: 2px solid var(--color-border-default);
|
|
35
35
|
|
|
36
36
|
transition:
|
|
37
37
|
border-color 120ms ease,
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
.default {
|
|
89
|
-
border-color:
|
|
89
|
+
border-color: var(--color-border-strong);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/* Sizes */
|
|
@@ -25,7 +25,7 @@ export interface MenuItemProps extends React.LiHTMLAttributes<HTMLLIElement> {
|
|
|
25
25
|
*/
|
|
26
26
|
itemRole?: 'menuitem' | 'option';
|
|
27
27
|
/** Adds a rounded border around the item */
|
|
28
|
-
variant?: 'default' | 'bordered';
|
|
28
|
+
variant?: 'default' | 'bordered' | 'danger';
|
|
29
29
|
}
|
|
30
30
|
export interface MenuCheckItemProps extends Omit<React.LiHTMLAttributes<HTMLLIElement>, 'onChange'> {
|
|
31
31
|
label: React.ReactNode;
|
|
@@ -90,17 +90,25 @@ const MenuItem = React.forwardRef(({ children, active, selected, disabled, class
|
|
|
90
90
|
// (We can’t reliably read parent props here without context; simplest is: caller passes itemRole on Menu.Item when needed.)
|
|
91
91
|
const resolvedRole = itemRole !== null && itemRole !== void 0 ? itemRole : 'menuitem';
|
|
92
92
|
const isBordered = variant === 'bordered';
|
|
93
|
+
const itemClassName = variant === 'danger' ? styles.itemDanger : undefined;
|
|
93
94
|
const rowClass = [styles.row, isBordered ? styles.rowBordered : '', className]
|
|
94
95
|
.filter(Boolean)
|
|
95
96
|
.join(' ');
|
|
96
97
|
if (isInteractiveEl(children)) {
|
|
97
98
|
const child = children;
|
|
98
|
-
return (_jsx("li", { ref: ref, role: "none", className: rowClass, ...liProps, children: applyMenuItemPropsToElement(child, {
|
|
99
|
+
return (_jsx("li", { ref: ref, role: "none", className: rowClass, ...liProps, children: applyMenuItemPropsToElement(child, {
|
|
100
|
+
active,
|
|
101
|
+
selected,
|
|
102
|
+
disabled,
|
|
103
|
+
role: resolvedRole,
|
|
104
|
+
className: itemClassName,
|
|
105
|
+
}) }));
|
|
99
106
|
}
|
|
100
107
|
// Fallback: wrap non-interactive children in a <button>
|
|
101
108
|
return (_jsx("li", { ref: ref, role: "none", className: rowClass, ...liProps, children: _jsx("button", { role: resolvedRole, tabIndex: 0, "aria-selected": selected || undefined, "aria-disabled": disabled || undefined, className: [
|
|
102
109
|
styles.interactive,
|
|
103
110
|
styles.item,
|
|
111
|
+
itemClassName,
|
|
104
112
|
active ? styles.active : '',
|
|
105
113
|
selected ? styles.selected : '',
|
|
106
114
|
]
|
|
@@ -132,7 +140,16 @@ const MenuCheckItem = React.forwardRef(({ label, checked, active, disabled, inte
|
|
|
132
140
|
});
|
|
133
141
|
MenuCheckItem.displayName = 'Menu.CheckItem';
|
|
134
142
|
const MenuRadioItem = React.forwardRef(({ name, value, checked, disabled, label, onValueChange, className, ...liProps }, ref) => {
|
|
135
|
-
return (_jsx("li", { ref: ref, role: "none", className: [styles.row, className].filter(Boolean).join(' '), ...liProps, children: _jsx("div", { className: styles.interactiveChild,
|
|
143
|
+
return (_jsx("li", { ref: ref, role: "none", className: [styles.row, className].filter(Boolean).join(' '), ...liProps, children: _jsx("div", { className: styles.interactiveChild, onClick: event => {
|
|
144
|
+
var _a;
|
|
145
|
+
if (disabled)
|
|
146
|
+
return;
|
|
147
|
+
const target = event.target;
|
|
148
|
+
// Let native label/input clicks handle themselves to avoid double-firing
|
|
149
|
+
if ((_a = target.closest('label')) !== null && _a !== void 0 ? _a : target.closest('input'))
|
|
150
|
+
return;
|
|
151
|
+
onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(value);
|
|
152
|
+
}, children: _jsx(RadioButton, { noContainer: true, name: name, value: value, checked: checked, disabled: disabled, label: label, onChange: (v, _e) => onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(v) }) }) }));
|
|
136
153
|
});
|
|
137
154
|
MenuRadioItem.displayName = 'Menu.RadioItem';
|
|
138
155
|
const MenuSeparator = React.forwardRef(({ className, ...props }, ref) => (_jsx("li", { ref: ref, role: "separator", className: [styles.separator, className].filter(Boolean).join(' '), ...props })));
|
|
@@ -70,11 +70,6 @@
|
|
|
70
70
|
cursor: pointer;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
/* NEW: let Checkbox/Radio consume full width so the hover area feels right */
|
|
74
|
-
.row > .interactiveChild > * {
|
|
75
|
-
inline-size: 100%;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
73
|
/* NEW: add consistent gap between control and label inside Checkbox/Radio
|
|
79
74
|
Both components use a root element with className={styles.container}.
|
|
80
75
|
Because they're CSS modules, we must target it with :global(.container). */
|
|
@@ -149,6 +144,14 @@
|
|
|
149
144
|
color: var(--color-fg-default);
|
|
150
145
|
}
|
|
151
146
|
|
|
147
|
+
.itemDanger {
|
|
148
|
+
color: var(--color-status-error);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.itemDanger svg {
|
|
152
|
+
color: inherit;
|
|
153
|
+
}
|
|
154
|
+
|
|
152
155
|
/* Disabled: support both cases */
|
|
153
156
|
.interactive[aria-disabled='true'],
|
|
154
157
|
.interactive:disabled,
|
|
@@ -161,8 +164,11 @@
|
|
|
161
164
|
/* Icons inside either interactive element or wrapper */
|
|
162
165
|
.interactive svg,
|
|
163
166
|
.interactiveChild svg {
|
|
164
|
-
inline-size: var(--icon-size-
|
|
165
|
-
block-size: var(--icon-size-
|
|
167
|
+
inline-size: var(--icon-size-sm);
|
|
168
|
+
block-size: var(--icon-size-sm);
|
|
169
|
+
/* Vertically center the icon against the first text line when parent is flex-start */
|
|
170
|
+
margin-block: calc((var(--line-height-normal) * var(--font-size-sm) - var(--icon-size-sm)) / 2);
|
|
171
|
+
flex-shrink: 0;
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
/* Visual separator row (used by <Menu.Separator />) */
|
|
@@ -5,6 +5,16 @@ import * as React from 'react';
|
|
|
5
5
|
import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useLayoutEffect, useRef, useState, } from 'react';
|
|
6
6
|
import { createPortal } from 'react-dom';
|
|
7
7
|
import styles from './Popover.module.css';
|
|
8
|
+
function assignRef(ref, value) {
|
|
9
|
+
if (!ref)
|
|
10
|
+
return;
|
|
11
|
+
if (typeof ref === 'function') {
|
|
12
|
+
ref(value);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
;
|
|
16
|
+
ref.current = value;
|
|
17
|
+
}
|
|
8
18
|
function getFocusable(container) {
|
|
9
19
|
const els = container.querySelectorAll([
|
|
10
20
|
'a[href]',
|
|
@@ -38,7 +48,7 @@ function parseMinWidthPx(minWidth, elForEm) {
|
|
|
38
48
|
}
|
|
39
49
|
return 0;
|
|
40
50
|
}
|
|
41
|
-
export const Popover = forwardRef(function Popover({ trigger: Trigger, children, open, defaultOpen = false, onOpenChange, contentId, minWidth = '200px', matchTriggerWidth = true, viewportPadding = 8, edgeBuffer = 100, dataCy, fullWidth = false, fillTrigger = false, autoFocusContent = false, returnFocus = true, anchorRef, overlayRef, }, ref) {
|
|
51
|
+
export const Popover = forwardRef(function Popover({ trigger: Trigger, children, open, defaultOpen = false, onOpenChange, contentId, minWidth = '200px', matchTriggerWidth = true, viewportPadding = 8, contentMaxHeightPx = 400, edgeBuffer = 100, dataCy, fullWidth = false, fillTrigger = false, autoFocusContent = false, returnFocus = true, anchorRef, overlayRef, }, ref) {
|
|
42
52
|
const internalId = useId();
|
|
43
53
|
const resolvedContentId = contentId !== null && contentId !== void 0 ? contentId : `popover-${internalId}`;
|
|
44
54
|
const isControlled = open !== undefined;
|
|
@@ -211,14 +221,7 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
211
221
|
}, [isOpen, returnFocus]);
|
|
212
222
|
const icon = isOpen ? _jsx(ChevronUp, { size: 20 }) : _jsx(ChevronDown, { size: 20 });
|
|
213
223
|
const setOverlayRef = React.useCallback((node) => {
|
|
214
|
-
|
|
215
|
-
return;
|
|
216
|
-
if (typeof overlayRef === 'function') {
|
|
217
|
-
overlayRef(node);
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
const mutableRef = overlayRef;
|
|
221
|
-
mutableRef.current = node;
|
|
224
|
+
assignRef(overlayRef, node);
|
|
222
225
|
}, [overlayRef]);
|
|
223
226
|
return (_jsxs("div", { className: [
|
|
224
227
|
styles.container,
|
|
@@ -244,7 +247,7 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
244
247
|
minWidth,
|
|
245
248
|
width: triggerWidth != null ? `${triggerWidth}px` : undefined,
|
|
246
249
|
maxWidth: `calc(100vw - ${viewportPadding * 2}px)`,
|
|
247
|
-
maxHeight: `clamp(100px, calc(100vh - ${viewportPadding * 2}px),
|
|
250
|
+
maxHeight: `clamp(100px, calc(100vh - ${viewportPadding * 2}px), ${contentMaxHeightPx}px)`,
|
|
248
251
|
visibility: positioned ? undefined : 'hidden',
|
|
249
252
|
}, "data-cy": dataCy !== null && dataCy !== void 0 ? dataCy : 'popover-content', children: typeof children === 'function'
|
|
250
253
|
? children(() => closePopover('api'))
|
|
@@ -38,15 +38,15 @@
|
|
|
38
38
|
|
|
39
39
|
.content {
|
|
40
40
|
position: fixed;
|
|
41
|
-
border: 1px solid var(--color-border-
|
|
41
|
+
border: 1px solid var(--color-border-subtle);
|
|
42
42
|
background-color: var(--color-bg-surface);
|
|
43
|
-
border-radius: var(--border-radius-
|
|
43
|
+
border-radius: var(--border-radius-lg);
|
|
44
44
|
padding: 0;
|
|
45
45
|
z-index: var(--z-popover);
|
|
46
46
|
overflow: auto;
|
|
47
47
|
box-shadow:
|
|
48
|
-
0 0 0 1px
|
|
49
|
-
var(--shadow-
|
|
48
|
+
0 0 0 1px rgba(0, 0, 0, 0.01),
|
|
49
|
+
var(--shadow-sm);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.content[hidden] {
|