@dbcdk/react-components 0.0.149 → 0.0.151
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/switch/Switch.cjs +4 -1
- package/dist/components/forms/switch/Switch.d.ts +11 -1
- package/dist/components/forms/switch/Switch.js +4 -1
- package/dist/components/forms/switch/Switch.module.css +6 -0
- package/dist/components/menu/Menu.cjs +116 -7
- package/dist/components/menu/Menu.d.ts +28 -0
- package/dist/components/menu/Menu.js +117 -8
- package/dist/components/menu/Menu.module.css +39 -1
- package/dist/components/overlay/modal/Modal.cjs +2 -0
- package/dist/components/overlay/modal/Modal.d.ts +2 -1
- package/dist/components/overlay/modal/Modal.js +2 -0
- package/dist/styles/styles.css +1 -1
- package/dist/styles/themes/dbc/colors.css +4 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/styles/themes/forfatterweb/light.css +0 -121
- package/dist/themes/forfatterweb.css +0 -2
|
@@ -18,6 +18,8 @@ function Switch({
|
|
|
18
18
|
modified,
|
|
19
19
|
label,
|
|
20
20
|
labelAs = "label",
|
|
21
|
+
endAdornment,
|
|
22
|
+
endAdornmentAriaHidden = true,
|
|
21
23
|
size = "md",
|
|
22
24
|
containerLabel,
|
|
23
25
|
error,
|
|
@@ -64,7 +66,8 @@ function Switch({
|
|
|
64
66
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.thumb, "aria-hidden": "true" })
|
|
65
67
|
}
|
|
66
68
|
) }),
|
|
67
|
-
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 }))
|
|
69
|
+
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 })),
|
|
70
|
+
endAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
68
71
|
]
|
|
69
72
|
}
|
|
70
73
|
);
|
|
@@ -9,6 +9,16 @@ interface SwitchProps {
|
|
|
9
9
|
modified?: boolean;
|
|
10
10
|
label?: ReactNode;
|
|
11
11
|
labelAs?: 'label' | 'span';
|
|
12
|
+
/**
|
|
13
|
+
* Extra content rendered after the label (e.g. a status dot or badge).
|
|
14
|
+
* The component owns the layout/spacing for this slot.
|
|
15
|
+
*/
|
|
16
|
+
endAdornment?: ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Whether the endAdornment wrapper is hidden from assistive tech.
|
|
19
|
+
* Defaults to true since endAdornment is typically decorative.
|
|
20
|
+
*/
|
|
21
|
+
endAdornmentAriaHidden?: boolean;
|
|
12
22
|
size?: Size;
|
|
13
23
|
containerLabel?: string;
|
|
14
24
|
error?: string;
|
|
@@ -23,5 +33,5 @@ interface SwitchProps {
|
|
|
23
33
|
tooltip?: ReactNode;
|
|
24
34
|
tooltipPlacement?: TooltipPlacement;
|
|
25
35
|
}
|
|
26
|
-
export declare function Switch({ checked: controlled, onChange, disabled, modified, label, labelAs, size, containerLabel, error, helpText, orientation, labelWidth, fullWidth, required, noContainer, id, 'data-cy': dataCy, tooltip, tooltipPlacement, }: SwitchProps): JSX.Element;
|
|
36
|
+
export declare function Switch({ checked: controlled, onChange, disabled, modified, label, labelAs, endAdornment, endAdornmentAriaHidden, size, containerLabel, error, helpText, orientation, labelWidth, fullWidth, required, noContainer, id, 'data-cy': dataCy, tooltip, tooltipPlacement, }: SwitchProps): JSX.Element;
|
|
27
37
|
export {};
|
|
@@ -12,6 +12,8 @@ function Switch({
|
|
|
12
12
|
modified,
|
|
13
13
|
label,
|
|
14
14
|
labelAs = "label",
|
|
15
|
+
endAdornment,
|
|
16
|
+
endAdornmentAriaHidden = true,
|
|
15
17
|
size = "md",
|
|
16
18
|
containerLabel,
|
|
17
19
|
error,
|
|
@@ -58,7 +60,8 @@ function Switch({
|
|
|
58
60
|
children: /* @__PURE__ */ jsx("span", { className: styles.thumb, "aria-hidden": "true" })
|
|
59
61
|
}
|
|
60
62
|
) }),
|
|
61
|
-
label && (labelAs === "label" ? /* @__PURE__ */ jsx("label", { className: styles.label, htmlFor: controlId, children: label }) : /* @__PURE__ */ jsx("span", { className: styles.label, children: label }))
|
|
63
|
+
label && (labelAs === "label" ? /* @__PURE__ */ jsx("label", { className: styles.label, htmlFor: controlId, children: label }) : /* @__PURE__ */ jsx("span", { className: styles.label, children: label })),
|
|
64
|
+
endAdornment && /* @__PURE__ */ jsx("span", { className: styles.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
62
65
|
]
|
|
63
66
|
}
|
|
64
67
|
);
|
|
@@ -6,6 +6,7 @@ var React = require('react');
|
|
|
6
6
|
var styles = require('./Menu.module.css');
|
|
7
7
|
var Checkbox = require('../forms/checkbox/Checkbox');
|
|
8
8
|
var RadioButton = require('../forms/radio-buttons/RadioButton');
|
|
9
|
+
var Switch = require('../forms/switch/Switch');
|
|
9
10
|
|
|
10
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
12
|
|
|
@@ -82,8 +83,23 @@ MenuBase.displayName = "Menu";
|
|
|
82
83
|
const isInteractiveEl = (el) => React__namespace.isValidElement(el) && (typeof el.type === "string" ? el.type === "a" || el.type === "button" : true);
|
|
83
84
|
function applyMenuItemPropsToElement(child, opts) {
|
|
84
85
|
var _a, _b, _c, _d;
|
|
85
|
-
const {
|
|
86
|
+
const {
|
|
87
|
+
active,
|
|
88
|
+
selected,
|
|
89
|
+
disabled,
|
|
90
|
+
role,
|
|
91
|
+
tabIndex = 0,
|
|
92
|
+
className,
|
|
93
|
+
endAdornment,
|
|
94
|
+
endAdornmentAriaHidden = true
|
|
95
|
+
} = opts;
|
|
86
96
|
const childClass = [styles__default.default.item, active ? styles__default.default.active : "", selected ? styles__default.default.selected : ""].filter(Boolean).join(" ");
|
|
97
|
+
const endAdornmentProps = endAdornment ? {
|
|
98
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
99
|
+
child.props.children,
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
101
|
+
] })
|
|
102
|
+
} : {};
|
|
87
103
|
const nextImmediate = React__namespace.cloneElement(child, {
|
|
88
104
|
className: [child.props.className, styles__default.default.interactiveChild, className].filter(Boolean).join(" ")
|
|
89
105
|
});
|
|
@@ -94,7 +110,8 @@ function applyMenuItemPropsToElement(child, opts) {
|
|
|
94
110
|
"aria-selected": selected || void 0,
|
|
95
111
|
"aria-disabled": disabled || void 0,
|
|
96
112
|
className: [child.props.className, styles__default.default.interactive, childClass, className].filter(Boolean).join(" "),
|
|
97
|
-
...child.type === "button" ? { disabled } : {}
|
|
113
|
+
...child.type === "button" ? { disabled } : {},
|
|
114
|
+
...endAdornmentProps
|
|
98
115
|
});
|
|
99
116
|
}
|
|
100
117
|
return React__namespace.cloneElement(nextImmediate, {
|
|
@@ -103,11 +120,23 @@ function applyMenuItemPropsToElement(child, opts) {
|
|
|
103
120
|
"aria-selected": selected || void 0,
|
|
104
121
|
"aria-disabled": disabled || void 0,
|
|
105
122
|
className: [nextImmediate.props.className, styles__default.default.interactive, childClass].filter(Boolean).join(" "),
|
|
106
|
-
disabled
|
|
123
|
+
disabled,
|
|
124
|
+
...endAdornmentProps
|
|
107
125
|
});
|
|
108
126
|
}
|
|
109
127
|
const MenuItem = React__namespace.forwardRef(
|
|
110
|
-
({
|
|
128
|
+
({
|
|
129
|
+
children,
|
|
130
|
+
active,
|
|
131
|
+
selected,
|
|
132
|
+
disabled,
|
|
133
|
+
className,
|
|
134
|
+
itemRole,
|
|
135
|
+
variant,
|
|
136
|
+
endAdornment,
|
|
137
|
+
endAdornmentAriaHidden = true,
|
|
138
|
+
...liProps
|
|
139
|
+
}, ref) => {
|
|
111
140
|
const resolvedRole = itemRole != null ? itemRole : "menuitem";
|
|
112
141
|
const isBordered = variant === "bordered";
|
|
113
142
|
const itemClassName = variant === "danger" ? styles__default.default.itemDanger : void 0;
|
|
@@ -119,10 +148,12 @@ const MenuItem = React__namespace.forwardRef(
|
|
|
119
148
|
selected,
|
|
120
149
|
disabled,
|
|
121
150
|
role: resolvedRole,
|
|
122
|
-
className: itemClassName
|
|
151
|
+
className: itemClassName,
|
|
152
|
+
endAdornment,
|
|
153
|
+
endAdornmentAriaHidden
|
|
123
154
|
}) });
|
|
124
155
|
}
|
|
125
|
-
return /* @__PURE__ */ jsxRuntime.jsx("li", { ref, role: "none", className: rowClass, ...liProps, children: /* @__PURE__ */ jsxRuntime.
|
|
156
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { ref, role: "none", className: rowClass, ...liProps, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
126
157
|
"button",
|
|
127
158
|
{
|
|
128
159
|
role: resolvedRole,
|
|
@@ -138,7 +169,10 @@ const MenuItem = React__namespace.forwardRef(
|
|
|
138
169
|
].filter(Boolean).join(" "),
|
|
139
170
|
type: "button",
|
|
140
171
|
disabled,
|
|
141
|
-
children
|
|
172
|
+
children: [
|
|
173
|
+
children,
|
|
174
|
+
endAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
175
|
+
]
|
|
142
176
|
}
|
|
143
177
|
) });
|
|
144
178
|
}
|
|
@@ -295,6 +329,79 @@ const MenuRadioItem = React__namespace.forwardRef(
|
|
|
295
329
|
}
|
|
296
330
|
);
|
|
297
331
|
MenuRadioItem.displayName = "Menu.RadioItem";
|
|
332
|
+
const MenuSwitchItem = React__namespace.forwardRef(
|
|
333
|
+
({
|
|
334
|
+
label,
|
|
335
|
+
checked,
|
|
336
|
+
active,
|
|
337
|
+
disabled,
|
|
338
|
+
interactiveRef,
|
|
339
|
+
interactiveProps,
|
|
340
|
+
onCheckedChange,
|
|
341
|
+
endAdornment,
|
|
342
|
+
endAdornmentAriaHidden,
|
|
343
|
+
className,
|
|
344
|
+
...liProps
|
|
345
|
+
}, ref) => {
|
|
346
|
+
const isSelected = checked;
|
|
347
|
+
const interactiveClass = [
|
|
348
|
+
styles__default.default.interactiveChild,
|
|
349
|
+
styles__default.default.item,
|
|
350
|
+
active ? styles__default.default.active : "",
|
|
351
|
+
isSelected ? styles__default.default.selected : ""
|
|
352
|
+
].filter(Boolean).join(" ");
|
|
353
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
354
|
+
"li",
|
|
355
|
+
{
|
|
356
|
+
ref,
|
|
357
|
+
role: "none",
|
|
358
|
+
className: [styles__default.default.row, className].filter(Boolean).join(" "),
|
|
359
|
+
...liProps,
|
|
360
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
361
|
+
"div",
|
|
362
|
+
{
|
|
363
|
+
ref: interactiveRef,
|
|
364
|
+
role: interactiveProps == null ? void 0 : interactiveProps.role,
|
|
365
|
+
tabIndex: -1,
|
|
366
|
+
"aria-selected": isSelected || void 0,
|
|
367
|
+
"aria-disabled": disabled || void 0,
|
|
368
|
+
className: interactiveClass,
|
|
369
|
+
...interactiveProps,
|
|
370
|
+
onClick: (event) => {
|
|
371
|
+
var _a;
|
|
372
|
+
(_a = interactiveProps == null ? void 0 : interactiveProps.onClick) == null ? void 0 : _a.call(interactiveProps, event);
|
|
373
|
+
if (event.defaultPrevented || disabled) return;
|
|
374
|
+
const target = event.target;
|
|
375
|
+
if (target instanceof Element && target.closest("button") !== null) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
onCheckedChange == null ? void 0 : onCheckedChange(!checked);
|
|
379
|
+
},
|
|
380
|
+
children: [
|
|
381
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.label, children: label }),
|
|
382
|
+
endAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.endAdornment, "aria-hidden": endAdornmentAriaHidden != null ? endAdornmentAriaHidden : true, children: endAdornment }),
|
|
383
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.switchControl, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
384
|
+
Switch.Switch,
|
|
385
|
+
{
|
|
386
|
+
size: "sm",
|
|
387
|
+
noContainer: true,
|
|
388
|
+
checked,
|
|
389
|
+
disabled,
|
|
390
|
+
onChange: (next, _e) => onCheckedChange == null ? void 0 : onCheckedChange(next)
|
|
391
|
+
}
|
|
392
|
+
) })
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
)
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
MenuSwitchItem.displayName = "Menu.SwitchItem";
|
|
401
|
+
const MenuLabel = React__namespace.forwardRef(
|
|
402
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: [styles__default.default.label, className].filter(Boolean).join(" "), ...props })
|
|
403
|
+
);
|
|
404
|
+
MenuLabel.displayName = "Menu.Label";
|
|
298
405
|
const MenuSeparator = React__namespace.forwardRef(
|
|
299
406
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
300
407
|
"li",
|
|
@@ -325,6 +432,8 @@ const Menu = Object.assign(MenuBase, {
|
|
|
325
432
|
Item: MenuItem,
|
|
326
433
|
CheckItem: MenuCheckItem,
|
|
327
434
|
RadioItem: MenuRadioItem,
|
|
435
|
+
SwitchItem: MenuSwitchItem,
|
|
436
|
+
Label: MenuLabel,
|
|
328
437
|
Separator: MenuSeparator,
|
|
329
438
|
Header: MenuHeader
|
|
330
439
|
});
|
|
@@ -10,6 +10,7 @@ export interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
|
10
10
|
/** Adds a gap of --spacing-xs between items */
|
|
11
11
|
gap?: boolean;
|
|
12
12
|
}
|
|
13
|
+
export type MenuLabelProps = React.HTMLAttributes<HTMLSpanElement>;
|
|
13
14
|
export type MenuSeparatorProps = React.LiHTMLAttributes<HTMLLIElement>;
|
|
14
15
|
export interface MenuHeaderProps extends React.LiHTMLAttributes<HTMLLIElement> {
|
|
15
16
|
children: React.ReactNode;
|
|
@@ -26,6 +27,15 @@ export interface MenuItemProps extends React.LiHTMLAttributes<HTMLLIElement> {
|
|
|
26
27
|
itemRole?: 'menuitem' | 'option';
|
|
27
28
|
/** Adds a rounded border around the item */
|
|
28
29
|
variant?: 'default' | 'bordered' | 'danger';
|
|
30
|
+
/**
|
|
31
|
+
* Extra content rendered after `children` (e.g. a status dot or badge).
|
|
32
|
+
* Appended as a trailing, vertically-centered slot inside the interactive
|
|
33
|
+
* element, so `children` stays exactly the icon + label content it was
|
|
34
|
+
* before — no need to know about `Menu.Label`.
|
|
35
|
+
*/
|
|
36
|
+
endAdornment?: React.ReactNode;
|
|
37
|
+
/** Forwarded to the endAdornment wrapper. Defaults to true. */
|
|
38
|
+
endAdornmentAriaHidden?: boolean;
|
|
29
39
|
}
|
|
30
40
|
export interface MenuCheckItemProps extends Omit<React.LiHTMLAttributes<HTMLLIElement>, 'onChange'> {
|
|
31
41
|
label: React.ReactNode;
|
|
@@ -61,10 +71,28 @@ export interface MenuRadioItemProps extends Omit<React.LiHTMLAttributes<HTMLLIEl
|
|
|
61
71
|
/** Forwarded to the underlying RadioButton. Defaults to true. */
|
|
62
72
|
endAdornmentAriaHidden?: boolean;
|
|
63
73
|
}
|
|
74
|
+
export interface MenuSwitchItemProps extends Omit<React.LiHTMLAttributes<HTMLLIElement>, 'onChange'> {
|
|
75
|
+
label: React.ReactNode;
|
|
76
|
+
checked: boolean;
|
|
77
|
+
active?: boolean;
|
|
78
|
+
disabled?: boolean;
|
|
79
|
+
interactiveRef?: React.Ref<HTMLDivElement>;
|
|
80
|
+
interactiveProps?: React.HTMLAttributes<HTMLDivElement>;
|
|
81
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
82
|
+
/**
|
|
83
|
+
* Extra content rendered after the label (e.g. a status dot or badge).
|
|
84
|
+
* Forwarded to the underlying Switch, which owns the layout/spacing.
|
|
85
|
+
*/
|
|
86
|
+
endAdornment?: React.ReactNode;
|
|
87
|
+
/** Forwarded to the underlying Switch. Defaults to true. */
|
|
88
|
+
endAdornmentAriaHidden?: boolean;
|
|
89
|
+
}
|
|
64
90
|
export declare const Menu: React.ForwardRefExoticComponent<MenuProps & React.RefAttributes<HTMLUListElement>> & {
|
|
65
91
|
Item: React.ForwardRefExoticComponent<MenuItemProps & React.RefAttributes<HTMLLIElement>>;
|
|
66
92
|
CheckItem: React.ForwardRefExoticComponent<MenuCheckItemProps & React.RefAttributes<HTMLLIElement>>;
|
|
67
93
|
RadioItem: React.ForwardRefExoticComponent<MenuRadioItemProps & React.RefAttributes<HTMLLIElement>>;
|
|
94
|
+
SwitchItem: React.ForwardRefExoticComponent<MenuSwitchItemProps & React.RefAttributes<HTMLLIElement>>;
|
|
68
95
|
Separator: React.ForwardRefExoticComponent<MenuSeparatorProps & React.RefAttributes<HTMLLIElement>>;
|
|
69
96
|
Header: React.ForwardRefExoticComponent<MenuHeaderProps & React.RefAttributes<HTMLLIElement>>;
|
|
97
|
+
Label: React.ForwardRefExoticComponent<MenuLabelProps & React.RefAttributes<HTMLSpanElement>>;
|
|
70
98
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import styles from './Menu.module.css';
|
|
5
5
|
import { Checkbox } from '../forms/checkbox/Checkbox';
|
|
6
6
|
import { RadioButton } from '../forms/radio-buttons/RadioButton';
|
|
7
|
+
import { Switch } from '../forms/switch/Switch';
|
|
7
8
|
|
|
8
9
|
const INTERACTIVE_SELECTOR = 'a:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"]):not([aria-disabled="true"]), [role="menuitem"]:not([aria-disabled="true"]), [role="menuitemradio"]:not([aria-disabled="true"]), [role="menuitemcheckbox"]:not([aria-disabled="true"]), [role="option"]:not([aria-disabled="true"])';
|
|
9
10
|
function getMenuItems(el) {
|
|
@@ -57,8 +58,23 @@ MenuBase.displayName = "Menu";
|
|
|
57
58
|
const isInteractiveEl = (el) => React.isValidElement(el) && (typeof el.type === "string" ? el.type === "a" || el.type === "button" : true);
|
|
58
59
|
function applyMenuItemPropsToElement(child, opts) {
|
|
59
60
|
var _a, _b, _c, _d;
|
|
60
|
-
const {
|
|
61
|
+
const {
|
|
62
|
+
active,
|
|
63
|
+
selected,
|
|
64
|
+
disabled,
|
|
65
|
+
role,
|
|
66
|
+
tabIndex = 0,
|
|
67
|
+
className,
|
|
68
|
+
endAdornment,
|
|
69
|
+
endAdornmentAriaHidden = true
|
|
70
|
+
} = opts;
|
|
61
71
|
const childClass = [styles.item, active ? styles.active : "", selected ? styles.selected : ""].filter(Boolean).join(" ");
|
|
72
|
+
const endAdornmentProps = endAdornment ? {
|
|
73
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
74
|
+
child.props.children,
|
|
75
|
+
/* @__PURE__ */ jsx("span", { className: styles.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
76
|
+
] })
|
|
77
|
+
} : {};
|
|
62
78
|
const nextImmediate = React.cloneElement(child, {
|
|
63
79
|
className: [child.props.className, styles.interactiveChild, className].filter(Boolean).join(" ")
|
|
64
80
|
});
|
|
@@ -69,7 +85,8 @@ function applyMenuItemPropsToElement(child, opts) {
|
|
|
69
85
|
"aria-selected": selected || void 0,
|
|
70
86
|
"aria-disabled": disabled || void 0,
|
|
71
87
|
className: [child.props.className, styles.interactive, childClass, className].filter(Boolean).join(" "),
|
|
72
|
-
...child.type === "button" ? { disabled } : {}
|
|
88
|
+
...child.type === "button" ? { disabled } : {},
|
|
89
|
+
...endAdornmentProps
|
|
73
90
|
});
|
|
74
91
|
}
|
|
75
92
|
return React.cloneElement(nextImmediate, {
|
|
@@ -78,11 +95,23 @@ function applyMenuItemPropsToElement(child, opts) {
|
|
|
78
95
|
"aria-selected": selected || void 0,
|
|
79
96
|
"aria-disabled": disabled || void 0,
|
|
80
97
|
className: [nextImmediate.props.className, styles.interactive, childClass].filter(Boolean).join(" "),
|
|
81
|
-
disabled
|
|
98
|
+
disabled,
|
|
99
|
+
...endAdornmentProps
|
|
82
100
|
});
|
|
83
101
|
}
|
|
84
102
|
const MenuItem = React.forwardRef(
|
|
85
|
-
({
|
|
103
|
+
({
|
|
104
|
+
children,
|
|
105
|
+
active,
|
|
106
|
+
selected,
|
|
107
|
+
disabled,
|
|
108
|
+
className,
|
|
109
|
+
itemRole,
|
|
110
|
+
variant,
|
|
111
|
+
endAdornment,
|
|
112
|
+
endAdornmentAriaHidden = true,
|
|
113
|
+
...liProps
|
|
114
|
+
}, ref) => {
|
|
86
115
|
const resolvedRole = itemRole != null ? itemRole : "menuitem";
|
|
87
116
|
const isBordered = variant === "bordered";
|
|
88
117
|
const itemClassName = variant === "danger" ? styles.itemDanger : void 0;
|
|
@@ -94,10 +123,12 @@ const MenuItem = React.forwardRef(
|
|
|
94
123
|
selected,
|
|
95
124
|
disabled,
|
|
96
125
|
role: resolvedRole,
|
|
97
|
-
className: itemClassName
|
|
126
|
+
className: itemClassName,
|
|
127
|
+
endAdornment,
|
|
128
|
+
endAdornmentAriaHidden
|
|
98
129
|
}) });
|
|
99
130
|
}
|
|
100
|
-
return /* @__PURE__ */ jsx("li", { ref, role: "none", className: rowClass, ...liProps, children: /* @__PURE__ */
|
|
131
|
+
return /* @__PURE__ */ jsx("li", { ref, role: "none", className: rowClass, ...liProps, children: /* @__PURE__ */ jsxs(
|
|
101
132
|
"button",
|
|
102
133
|
{
|
|
103
134
|
role: resolvedRole,
|
|
@@ -113,7 +144,10 @@ const MenuItem = React.forwardRef(
|
|
|
113
144
|
].filter(Boolean).join(" "),
|
|
114
145
|
type: "button",
|
|
115
146
|
disabled,
|
|
116
|
-
children
|
|
147
|
+
children: [
|
|
148
|
+
children,
|
|
149
|
+
endAdornment && /* @__PURE__ */ jsx("span", { className: styles.endAdornment, "aria-hidden": endAdornmentAriaHidden, children: endAdornment })
|
|
150
|
+
]
|
|
117
151
|
}
|
|
118
152
|
) });
|
|
119
153
|
}
|
|
@@ -270,6 +304,79 @@ const MenuRadioItem = React.forwardRef(
|
|
|
270
304
|
}
|
|
271
305
|
);
|
|
272
306
|
MenuRadioItem.displayName = "Menu.RadioItem";
|
|
307
|
+
const MenuSwitchItem = React.forwardRef(
|
|
308
|
+
({
|
|
309
|
+
label,
|
|
310
|
+
checked,
|
|
311
|
+
active,
|
|
312
|
+
disabled,
|
|
313
|
+
interactiveRef,
|
|
314
|
+
interactiveProps,
|
|
315
|
+
onCheckedChange,
|
|
316
|
+
endAdornment,
|
|
317
|
+
endAdornmentAriaHidden,
|
|
318
|
+
className,
|
|
319
|
+
...liProps
|
|
320
|
+
}, ref) => {
|
|
321
|
+
const isSelected = checked;
|
|
322
|
+
const interactiveClass = [
|
|
323
|
+
styles.interactiveChild,
|
|
324
|
+
styles.item,
|
|
325
|
+
active ? styles.active : "",
|
|
326
|
+
isSelected ? styles.selected : ""
|
|
327
|
+
].filter(Boolean).join(" ");
|
|
328
|
+
return /* @__PURE__ */ jsx(
|
|
329
|
+
"li",
|
|
330
|
+
{
|
|
331
|
+
ref,
|
|
332
|
+
role: "none",
|
|
333
|
+
className: [styles.row, className].filter(Boolean).join(" "),
|
|
334
|
+
...liProps,
|
|
335
|
+
children: /* @__PURE__ */ jsxs(
|
|
336
|
+
"div",
|
|
337
|
+
{
|
|
338
|
+
ref: interactiveRef,
|
|
339
|
+
role: interactiveProps == null ? void 0 : interactiveProps.role,
|
|
340
|
+
tabIndex: -1,
|
|
341
|
+
"aria-selected": isSelected || void 0,
|
|
342
|
+
"aria-disabled": disabled || void 0,
|
|
343
|
+
className: interactiveClass,
|
|
344
|
+
...interactiveProps,
|
|
345
|
+
onClick: (event) => {
|
|
346
|
+
var _a;
|
|
347
|
+
(_a = interactiveProps == null ? void 0 : interactiveProps.onClick) == null ? void 0 : _a.call(interactiveProps, event);
|
|
348
|
+
if (event.defaultPrevented || disabled) return;
|
|
349
|
+
const target = event.target;
|
|
350
|
+
if (target instanceof Element && target.closest("button") !== null) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
onCheckedChange == null ? void 0 : onCheckedChange(!checked);
|
|
354
|
+
},
|
|
355
|
+
children: [
|
|
356
|
+
/* @__PURE__ */ jsx("span", { className: styles.label, children: label }),
|
|
357
|
+
endAdornment && /* @__PURE__ */ jsx("span", { className: styles.endAdornment, "aria-hidden": endAdornmentAriaHidden != null ? endAdornmentAriaHidden : true, children: endAdornment }),
|
|
358
|
+
/* @__PURE__ */ jsx("span", { className: styles.switchControl, children: /* @__PURE__ */ jsx(
|
|
359
|
+
Switch,
|
|
360
|
+
{
|
|
361
|
+
size: "sm",
|
|
362
|
+
noContainer: true,
|
|
363
|
+
checked,
|
|
364
|
+
disabled,
|
|
365
|
+
onChange: (next, _e) => onCheckedChange == null ? void 0 : onCheckedChange(next)
|
|
366
|
+
}
|
|
367
|
+
) })
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
)
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
);
|
|
375
|
+
MenuSwitchItem.displayName = "Menu.SwitchItem";
|
|
376
|
+
const MenuLabel = React.forwardRef(
|
|
377
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("span", { ref, className: [styles.label, className].filter(Boolean).join(" "), ...props })
|
|
378
|
+
);
|
|
379
|
+
MenuLabel.displayName = "Menu.Label";
|
|
273
380
|
const MenuSeparator = React.forwardRef(
|
|
274
381
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
275
382
|
"li",
|
|
@@ -300,6 +407,8 @@ const Menu = Object.assign(MenuBase, {
|
|
|
300
407
|
Item: MenuItem,
|
|
301
408
|
CheckItem: MenuCheckItem,
|
|
302
409
|
RadioItem: MenuRadioItem,
|
|
410
|
+
SwitchItem: MenuSwitchItem,
|
|
411
|
+
Label: MenuLabel,
|
|
303
412
|
Separator: MenuSeparator,
|
|
304
413
|
Header: MenuHeader
|
|
305
414
|
});
|
|
@@ -39,13 +39,51 @@
|
|
|
39
39
|
color var(--transition-fast) var(--ease-standard);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
/* Default case: applies wrap-safety to whichever element ends up last,
|
|
43
|
+
e.g. a plain label with no `endAdornment` prop involved — covers most
|
|
44
|
+
Menu.Item usage as-is. Excluded once .endAdornment is present (it's then
|
|
45
|
+
always the true last child) — wrap the label in <Menu.Label> in that case,
|
|
46
|
+
since it's no longer last and needs the wrap styling explicitly. */
|
|
47
|
+
.interactive > :last-child:not(.endAdornment) {
|
|
43
48
|
min-width: 0;
|
|
44
49
|
white-space: normal;
|
|
45
50
|
overflow-wrap: anywhere;
|
|
46
51
|
word-break: break-word;
|
|
47
52
|
}
|
|
48
53
|
|
|
54
|
+
/* Explicit label slot (use <Menu.Label>) so wrap styling doesn't depend on
|
|
55
|
+
the label being the last child — needed once trailing content (the
|
|
56
|
+
`endAdornment` prop) is rendered after it. */
|
|
57
|
+
.label {
|
|
58
|
+
min-width: 0;
|
|
59
|
+
flex: 1 1 auto;
|
|
60
|
+
white-space: normal;
|
|
61
|
+
overflow-wrap: anywhere;
|
|
62
|
+
word-break: break-word;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Trailing content rendered via the `endAdornment` prop (e.g. a status
|
|
66
|
+
dot/badge). Centered on its own regardless of the row's flex-start
|
|
67
|
+
alignment, since it isn't tied to the first text line the way a leading
|
|
68
|
+
icon is. */
|
|
69
|
+
.endAdornment {
|
|
70
|
+
display: inline-flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
align-self: center;
|
|
73
|
+
flex: 0 0 auto;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Wraps a bare <Switch noContainer> in Menu.SwitchItem so it docks at the
|
|
77
|
+
end of the row (label/endAdornment are rendered by Menu, not Switch).
|
|
78
|
+
Shrink-proof: Switch's own `.container` still matches the generic
|
|
79
|
+
`.row :global(.container)` full-width rule below, but that now resolves
|
|
80
|
+
against this wrapper's own content width, not the whole row. */
|
|
81
|
+
.switchControl {
|
|
82
|
+
display: inline-flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
flex: 0 0 auto;
|
|
85
|
+
}
|
|
86
|
+
|
|
49
87
|
/*
|
|
50
88
|
Applied to the immediate child of <li> even if it's NOT an interactive element (e.g. a <div>)
|
|
51
89
|
so that menu row styling still works for components that render a wrapper.
|
|
@@ -18,6 +18,7 @@ function Modal({
|
|
|
18
18
|
onRequestClose,
|
|
19
19
|
header,
|
|
20
20
|
subheader,
|
|
21
|
+
headerAddition,
|
|
21
22
|
content,
|
|
22
23
|
children,
|
|
23
24
|
primaryAction,
|
|
@@ -143,6 +144,7 @@ function Modal({
|
|
|
143
144
|
size: 2,
|
|
144
145
|
disableMargin: true,
|
|
145
146
|
subheader,
|
|
147
|
+
addition: headerAddition,
|
|
146
148
|
children: header
|
|
147
149
|
}
|
|
148
150
|
),
|
|
@@ -14,6 +14,7 @@ export type ModalProps = {
|
|
|
14
14
|
onRequestClose: () => void;
|
|
15
15
|
header?: ReactNode;
|
|
16
16
|
subheader?: ReactNode;
|
|
17
|
+
headerAddition?: ReactNode;
|
|
17
18
|
content?: ReactNode;
|
|
18
19
|
children?: ReactNode;
|
|
19
20
|
primaryAction?: ModalActionConfig;
|
|
@@ -25,4 +26,4 @@ export type ModalProps = {
|
|
|
25
26
|
width?: number | string;
|
|
26
27
|
ariaLabel?: string;
|
|
27
28
|
};
|
|
28
|
-
export declare function Modal({ isOpen, onRequestClose, header, subheader, content, children, primaryAction, secondaryAction, closeOnOverlayClick, severity, disableContentSpacing, isLoading, dataCy, width, ariaLabel, }: ModalProps): React.ReactNode;
|
|
29
|
+
export declare function Modal({ isOpen, onRequestClose, header, subheader, headerAddition, content, children, primaryAction, secondaryAction, closeOnOverlayClick, severity, disableContentSpacing, isLoading, dataCy, width, ariaLabel, }: ModalProps): React.ReactNode;
|
|
@@ -12,6 +12,7 @@ function Modal({
|
|
|
12
12
|
onRequestClose,
|
|
13
13
|
header,
|
|
14
14
|
subheader,
|
|
15
|
+
headerAddition,
|
|
15
16
|
content,
|
|
16
17
|
children,
|
|
17
18
|
primaryAction,
|
|
@@ -137,6 +138,7 @@ function Modal({
|
|
|
137
138
|
size: 2,
|
|
138
139
|
disableMargin: true,
|
|
139
140
|
subheader,
|
|
141
|
+
addition: headerAddition,
|
|
140
142
|
children: header
|
|
141
143
|
}
|
|
142
144
|
),
|
package/dist/styles/styles.css
CHANGED
|
@@ -237,7 +237,7 @@ body.dbc-app {
|
|
|
237
237
|
color: var(--color-code-fg, inherit);
|
|
238
238
|
background-color: var(--color-code-bg, var(--color-bg-contextual));
|
|
239
239
|
border-radius: var(--border-radius-sm);
|
|
240
|
-
padding-inline: var(--spacing-
|
|
240
|
+
padding-inline: var(--spacing-xxs);
|
|
241
241
|
font-family: var(--font-family-mono);
|
|
242
242
|
font-size: 0.9em;
|
|
243
243
|
box-decoration-break: clone;
|
|
@@ -55,6 +55,8 @@ html {
|
|
|
55
55
|
|
|
56
56
|
--dbc-amber-700: light-dark(#b45309, #f59e0b);
|
|
57
57
|
--dbc-amber-100: light-dark(#fff7ed, #2b1b00);
|
|
58
|
+
/* Fixed (not light-dark): needs to stay a legible pale gold behind dark ink in both schemes */
|
|
59
|
+
--dbc-amber-200: #fde68a;
|
|
58
60
|
--dbc-amber-800: light-dark(#92400e, #fcd34d);
|
|
59
61
|
--dbc-amber-400: light-dark(#f59e0b, #fbbf24);
|
|
60
62
|
|
|
@@ -99,8 +101,8 @@ html {
|
|
|
99
101
|
--color-bg-selected-hover: var(--dbc-blue-150);
|
|
100
102
|
|
|
101
103
|
/* Highlight */
|
|
102
|
-
--color-highlight-bg: var(--
|
|
103
|
-
--color-highlight-fg:
|
|
104
|
+
--color-highlight-bg: var(--dbc-amber-200);
|
|
105
|
+
--color-highlight-fg: #1a1a1a;
|
|
104
106
|
|
|
105
107
|
--color-neutral: var(--dbc-neutral-200);
|
|
106
108
|
|
package/dist/styles.css
CHANGED
|
@@ -237,7 +237,7 @@ body.dbc-app {
|
|
|
237
237
|
color: var(--color-code-fg, inherit);
|
|
238
238
|
background-color: var(--color-code-bg, var(--color-bg-contextual));
|
|
239
239
|
border-radius: var(--border-radius-sm);
|
|
240
|
-
padding-inline: var(--spacing-
|
|
240
|
+
padding-inline: var(--spacing-xxs);
|
|
241
241
|
font-family: var(--font-family-mono);
|
|
242
242
|
font-size: 0.9em;
|
|
243
243
|
box-decoration-break: clone;
|
package/package.json
CHANGED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
/* Colors */
|
|
3
|
-
--color-primary: #1e88e5;
|
|
4
|
-
--color-primary-hover: #007bb0;
|
|
5
|
-
--color-highlight: #3b99e0;
|
|
6
|
-
--focus-ring: 0 0 0 2px #3b99e0;
|
|
7
|
-
--color-primary-hover: #0932b6;
|
|
8
|
-
--color-secondary: #6b7280;
|
|
9
|
-
--color-secondary-hover: #4b5563;
|
|
10
|
-
--color-accent: #ec4899;
|
|
11
|
-
--color-accent-hover: #be185d;
|
|
12
|
-
|
|
13
|
-
--color-highlight: #0932b6;
|
|
14
|
-
--color-hover: var(--opac-bg-light);
|
|
15
|
-
|
|
16
|
-
--color-background: #ffffff;
|
|
17
|
-
|
|
18
|
-
--color-text: #111827;
|
|
19
|
-
--color-text-on-primary: var(--color-text-inverse);
|
|
20
|
-
--color-text-on-highlight: var(--color-text-inverse);
|
|
21
|
-
--color-text-on-secondary: var(--color-text-inverse);
|
|
22
|
-
--color-text-muted: #6b7280;
|
|
23
|
-
--color-text-inverse: #ffffff;
|
|
24
|
-
|
|
25
|
-
--color-border: #e5e7eb;
|
|
26
|
-
--color-border-strong: #d1d5db;
|
|
27
|
-
|
|
28
|
-
--color-success: #16a34a;
|
|
29
|
-
--color-warning: #f59e0b;
|
|
30
|
-
--color-error: #dc2626;
|
|
31
|
-
--color-info: #0ea5e9;
|
|
32
|
-
|
|
33
|
-
--color-chart-empty: color-mix(in srgb, var(--color-text-muted) 15%, rgb(255 255 255 / 0));
|
|
34
|
-
--color-chart-neutral: color-mix(in srgb, var(--color-text-muted) 25%, rgb(255 255 255 / 0));
|
|
35
|
-
--color-chart-primary: color-mix(in srgb, var(--color-primary) 75%, rgb(255 255 255 / 0));
|
|
36
|
-
--color-chart-success: color-mix(in srgb, var(--color-success) 75%, rgb(255 255 255 / 0));
|
|
37
|
-
--color-chart-warning: color-mix(in srgb, var(--color-warning) 75%, rgb(255 255 255 / 0));
|
|
38
|
-
--color-chart-brand: color-mix(in srgb, var(--color-accent) 75%, rgb(255 255 255 / 0));
|
|
39
|
-
--color-chart-info: color-mix(in srgb, var(--color-info) 75%, rgb(255 255 255 / 0));
|
|
40
|
-
--color-chart-error: color-mix(in srgb, var(--color-error) 75%, rgb(255 255 255 / 0));
|
|
41
|
-
|
|
42
|
-
/* Legacy aliases */
|
|
43
|
-
--color-chart-blue: var(--color-chart-primary);
|
|
44
|
-
--color-chart-green: var(--color-chart-success);
|
|
45
|
-
--color-chart-amber: var(--color-chart-warning);
|
|
46
|
-
--color-chart-pink: var(--color-chart-brand);
|
|
47
|
-
--color-chart-sky: var(--color-chart-info);
|
|
48
|
-
--color-chart-red: var(--color-chart-error);
|
|
49
|
-
|
|
50
|
-
--opac-bg-light: rgba(0, 0, 0, 0.025);
|
|
51
|
-
--opac-bg-default: rgba(0, 0, 0, 0.05);
|
|
52
|
-
--opac-bg-dark: rgba(0, 0, 0, 0.1);
|
|
53
|
-
--opac-bg-dark-inverse: rgba(255, 255, 255, 0.1);
|
|
54
|
-
|
|
55
|
-
/* Spacing */
|
|
56
|
-
--spacing-xxs: 0.25rem;
|
|
57
|
-
--spacing-xs: 0.5rem;
|
|
58
|
-
--spacing-sm: 0.75rem;
|
|
59
|
-
--spacing-md: 1rem;
|
|
60
|
-
--spacing-lg: 1.5rem;
|
|
61
|
-
--spacing-xl: 2rem;
|
|
62
|
-
--spacing-2xl: 3rem;
|
|
63
|
-
|
|
64
|
-
--icon-size: 20px;
|
|
65
|
-
|
|
66
|
-
--component-size-xs: 1.5rem;
|
|
67
|
-
--component-size-sm: 2rem;
|
|
68
|
-
--component-size-md: 2.5rem;
|
|
69
|
-
--component-size-lg: 3rem;
|
|
70
|
-
--component-size-xl: 4rem;
|
|
71
|
-
|
|
72
|
-
/* Borders */
|
|
73
|
-
|
|
74
|
-
--border-width-thin: 1px;
|
|
75
|
-
--border-width-thick: 2px;
|
|
76
|
-
|
|
77
|
-
--border-radius-none: 0;
|
|
78
|
-
--border-radius-default: 0.25rem;
|
|
79
|
-
--border-radius-rounded: 2rem;
|
|
80
|
-
--border-radius-round: 50%;
|
|
81
|
-
|
|
82
|
-
/* Typography */
|
|
83
|
-
--font-family: Roboto, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
84
|
-
--font-family-mono: ui-monospace, SFMono-Regular, monospace;
|
|
85
|
-
|
|
86
|
-
--font-size-xs: 0.75rem;
|
|
87
|
-
--font-size-sm: 0.875rem;
|
|
88
|
-
--font-size-md: 1rem;
|
|
89
|
-
--font-size-lg: 1.25rem;
|
|
90
|
-
--font-size-xl: 2rem;
|
|
91
|
-
--font-size-2xl: 3rem;
|
|
92
|
-
|
|
93
|
-
--font-weight-regular: 400;
|
|
94
|
-
--font-weight-medium: 500;
|
|
95
|
-
--font-weight-bold: 700;
|
|
96
|
-
|
|
97
|
-
--line-height-tight: 1.25;
|
|
98
|
-
--line-height-normal: 1.5;
|
|
99
|
-
--line-height-relaxed: 1.75;
|
|
100
|
-
|
|
101
|
-
/* Overlay */
|
|
102
|
-
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
103
|
-
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
104
|
-
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
105
|
-
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
|
106
|
-
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1);
|
|
107
|
-
|
|
108
|
-
/* Transitions */
|
|
109
|
-
--transition-fast: 150ms ease-in-out;
|
|
110
|
-
--transition-normal: 250ms ease-in-out;
|
|
111
|
-
--transition-slow: 400ms ease-in-out;
|
|
112
|
-
|
|
113
|
-
--focus-ring: 0 0 0 2px var(--color-primary);
|
|
114
|
-
|
|
115
|
-
/* Layers */
|
|
116
|
-
--z-dropdown: 1000;
|
|
117
|
-
--z-sticky: 1100;
|
|
118
|
-
--z-modal: 1200;
|
|
119
|
-
--z-popover: 1300;
|
|
120
|
-
--z-tooltip: 1400;
|
|
121
|
-
}
|