@mediaradar/design-components 0.18.2 → 0.18.3
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/index.cjs +88 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -21
- package/dist/index.d.ts +30 -21
- package/dist/index.js +99 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -85,6 +85,17 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
85
85
|
const [open, setOpen] = (0, import_react.useState)(false);
|
|
86
86
|
const [pos, setPos] = (0, import_react.useState)(null);
|
|
87
87
|
const btnRef = (0, import_react.useRef)(null);
|
|
88
|
+
const closeTimer = (0, import_react.useRef)(null);
|
|
89
|
+
const textId = (0, import_react.useId)();
|
|
90
|
+
const cancelClose = () => {
|
|
91
|
+
if (closeTimer.current) clearTimeout(closeTimer.current);
|
|
92
|
+
closeTimer.current = null;
|
|
93
|
+
};
|
|
94
|
+
const closeSoon = () => {
|
|
95
|
+
cancelClose();
|
|
96
|
+
closeTimer.current = setTimeout(() => setOpen(false), 120);
|
|
97
|
+
};
|
|
98
|
+
(0, import_react.useEffect)(() => cancelClose, []);
|
|
88
99
|
(0, import_react.useEffect)(() => {
|
|
89
100
|
if (!open) return;
|
|
90
101
|
const onDown = (e) => {
|
|
@@ -106,6 +117,7 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
106
117
|
setPos({ top: r.bottom + 6, left, width });
|
|
107
118
|
};
|
|
108
119
|
const show = () => {
|
|
120
|
+
cancelClose();
|
|
109
121
|
place();
|
|
110
122
|
setOpen(true);
|
|
111
123
|
};
|
|
@@ -116,7 +128,7 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
116
128
|
};
|
|
117
129
|
const hoverProps = trigger === "hover" ? {
|
|
118
130
|
onMouseEnter: show,
|
|
119
|
-
onMouseLeave:
|
|
131
|
+
onMouseLeave: closeSoon,
|
|
120
132
|
onFocus: show,
|
|
121
133
|
onBlur: () => setOpen(false)
|
|
122
134
|
} : {};
|
|
@@ -129,16 +141,20 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
129
141
|
onClick: toggle,
|
|
130
142
|
"aria-label": label,
|
|
131
143
|
"aria-expanded": open,
|
|
144
|
+
"aria-describedby": textId,
|
|
132
145
|
...hoverProps,
|
|
133
146
|
className: "inline-flex cursor-pointer items-center text-text-tertiary transition-colors hover:text-text-primary focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-border-focus",
|
|
134
147
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Info, { size, "aria-hidden": "true" })
|
|
135
148
|
}
|
|
136
149
|
),
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { id: textId, hidden: true, children: text }),
|
|
137
151
|
open && pos && (0, import_react_dom.createPortal)(
|
|
138
152
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
139
153
|
"div",
|
|
140
154
|
{
|
|
141
|
-
|
|
155
|
+
"aria-hidden": "true",
|
|
156
|
+
onMouseEnter: trigger === "hover" ? cancelClose : void 0,
|
|
157
|
+
onMouseLeave: trigger === "hover" ? closeSoon : void 0,
|
|
142
158
|
style: { position: "fixed", top: pos.top, left: pos.left, width: pos.width },
|
|
143
159
|
className: "z-[90] rounded-control border border-border-default bg-surface px-3 py-2 text-[12px] font-normal not-italic normal-case leading-relaxed tracking-normal text-text-secondary shadow-overlay",
|
|
144
160
|
children: text
|
|
@@ -587,7 +603,7 @@ var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
|
587
603
|
function boxClass(on, disabled) {
|
|
588
604
|
return cn(
|
|
589
605
|
"flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
|
|
590
|
-
on ? "border-transparent bg-brand-primaryAction text-
|
|
606
|
+
on ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input",
|
|
591
607
|
disabled && "cursor-not-allowed opacity-50"
|
|
592
608
|
);
|
|
593
609
|
}
|
|
@@ -927,7 +943,7 @@ function DateRangeFilter({
|
|
|
927
943
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
928
944
|
"span",
|
|
929
945
|
{
|
|
930
|
-
className: `relative z-10 flex h-8 w-8 items-center justify-center rounded-full text-[13px] tabular-nums ${endpoint ? "bg-brand-primaryAction font-semibold text-
|
|
946
|
+
className: `relative z-10 flex h-8 w-8 items-center justify-center rounded-full text-[13px] tabular-nums ${endpoint ? "bg-brand-primaryAction font-semibold text-brand-onprimary" : inMonth ? "text-text-primary hover:bg-subtle" : "text-text-tertiary"}`,
|
|
931
947
|
children: d.getDate()
|
|
932
948
|
}
|
|
933
949
|
)
|
|
@@ -938,7 +954,7 @@ function DateRangeFilter({
|
|
|
938
954
|
}) }),
|
|
939
955
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mt-4 flex justify-end gap-2", children: [
|
|
940
956
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", "data-testid": testIdPrefix && `${testIdPrefix}-cancel`, onClick: () => setOpen(false), className: "rounded-control border border-border-default bg-surface px-5 py-2 text-[13px] font-semibold text-text-primary transition-colors hover:bg-subtle", children: "Cancel" }),
|
|
941
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", "data-testid": testIdPrefix && `${testIdPrefix}-apply`, onClick: apply, className: "rounded-control bg-brand-primaryAction px-5 py-2 text-[13px] font-semibold text-
|
|
957
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", "data-testid": testIdPrefix && `${testIdPrefix}-apply`, onClick: apply, className: "rounded-control bg-brand-primaryAction px-5 py-2 text-[13px] font-semibold text-brand-onprimary transition-[filter] hover:brightness-110", children: "Apply" })
|
|
942
958
|
] })
|
|
943
959
|
] })
|
|
944
960
|
]
|
|
@@ -1218,6 +1234,7 @@ function RadioOption({
|
|
|
1218
1234
|
}
|
|
1219
1235
|
function RowInfoTip({ text }) {
|
|
1220
1236
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1237
|
+
const id = (0, import_react4.useId)();
|
|
1221
1238
|
const ref = (0, import_react4.useRef)(null);
|
|
1222
1239
|
(0, import_react4.useEffect)(() => {
|
|
1223
1240
|
if (!open) return;
|
|
@@ -1238,14 +1255,16 @@ function RowInfoTip({ text }) {
|
|
|
1238
1255
|
},
|
|
1239
1256
|
"aria-label": "More information",
|
|
1240
1257
|
"aria-expanded": open,
|
|
1241
|
-
|
|
1258
|
+
"aria-describedby": id,
|
|
1259
|
+
className: "inline-flex text-text-tertiary transition-colors hover:text-text-primary focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-border-focus",
|
|
1242
1260
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react7.AlertCircle, { size: 13, "aria-hidden": "true" })
|
|
1243
1261
|
}
|
|
1244
1262
|
),
|
|
1245
|
-
|
|
1263
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1246
1264
|
"span",
|
|
1247
1265
|
{
|
|
1248
|
-
|
|
1266
|
+
id,
|
|
1267
|
+
hidden: !open,
|
|
1249
1268
|
className: "absolute left-0 top-[calc(100%+6px)] z-40 w-[220px] rounded-control border border-border-default bg-surface px-2.5 py-1.5 text-[11.5px] font-normal leading-snug text-text-secondary shadow-overlay",
|
|
1250
1269
|
children: text
|
|
1251
1270
|
}
|
|
@@ -1597,7 +1616,7 @@ var NO_RESULTS_BODY = "Your filters may be too narrow, conflict with each other,
|
|
|
1597
1616
|
function noResultsBody(workspaceName) {
|
|
1598
1617
|
return workspaceName ? `Nothing in the \u201C${workspaceName}\u201D workspace matches. ${NO_RESULTS_BODY}` : NO_RESULTS_BODY;
|
|
1599
1618
|
}
|
|
1600
|
-
var PRIMARY_ACTION_CLASS = "rounded-control bg-brand-primaryAction px-3.5 py-2 text-[13px] font-semibold text-
|
|
1619
|
+
var PRIMARY_ACTION_CLASS = "rounded-control bg-brand-primaryAction px-3.5 py-2 text-[13px] font-semibold text-brand-onprimary transition-colors hover:opacity-90";
|
|
1601
1620
|
var QUIET_ACTION_CLASS = "rounded-control text-[13px] font-medium text-text-link transition-colors hover:underline focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-border-focus";
|
|
1602
1621
|
function NoResultsEmptyState({
|
|
1603
1622
|
title = NO_RESULTS_TITLE,
|
|
@@ -1938,6 +1957,15 @@ var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
|
1938
1957
|
function cx6(...parts) {
|
|
1939
1958
|
return parts.filter(Boolean).join(" ");
|
|
1940
1959
|
}
|
|
1960
|
+
function addDescribedBy(el, id) {
|
|
1961
|
+
const ids = (el.getAttribute("aria-describedby") ?? "").split(" ").filter(Boolean);
|
|
1962
|
+
if (!ids.includes(id)) el.setAttribute("aria-describedby", [...ids, id].join(" "));
|
|
1963
|
+
}
|
|
1964
|
+
function removeDescribedBy(el, id) {
|
|
1965
|
+
const ids = (el.getAttribute("aria-describedby") ?? "").split(" ").filter((x) => x && x !== id);
|
|
1966
|
+
if (ids.length) el.setAttribute("aria-describedby", ids.join(" "));
|
|
1967
|
+
else el.removeAttribute("aria-describedby");
|
|
1968
|
+
}
|
|
1941
1969
|
function exitDurationMs(el) {
|
|
1942
1970
|
if (typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return 0;
|
|
1943
1971
|
const cs = window.getComputedStyle(el);
|
|
@@ -1975,6 +2003,7 @@ function Tooltip({
|
|
|
1975
2003
|
const openRef = (0, import_react10.useRef)(false);
|
|
1976
2004
|
const mountedRef = (0, import_react10.useRef)(false);
|
|
1977
2005
|
const id = (0, import_react10.useId)();
|
|
2006
|
+
const describedRef = (0, import_react10.useRef)(null);
|
|
1978
2007
|
const clearHideTimer = () => {
|
|
1979
2008
|
if (hideTimer.current) {
|
|
1980
2009
|
clearTimeout(hideTimer.current);
|
|
@@ -2011,7 +2040,8 @@ function Tooltip({
|
|
|
2011
2040
|
if (!mountedRef.current) setBoxWidth(null);
|
|
2012
2041
|
mountedRef.current = true;
|
|
2013
2042
|
setAnchor({ top: r.top, left: r.left, width: r.width, height: r.height, bottom: r.bottom, right: r.right });
|
|
2014
|
-
|
|
2043
|
+
const target = anchorRef ? el : describedRef.current;
|
|
2044
|
+
if (target) addDescribedBy(target, id);
|
|
2015
2045
|
};
|
|
2016
2046
|
const show = () => {
|
|
2017
2047
|
clearHideTimer();
|
|
@@ -2028,7 +2058,9 @@ function Tooltip({
|
|
|
2028
2058
|
mountedRef.current = false;
|
|
2029
2059
|
setAnchor(null);
|
|
2030
2060
|
setBoxWidth(null);
|
|
2031
|
-
if (anchorRef?.current) anchorRef.current
|
|
2061
|
+
if (anchorRef?.current) removeDescribedBy(anchorRef.current, id);
|
|
2062
|
+
if (describedRef.current) removeDescribedBy(describedRef.current, id);
|
|
2063
|
+
describedRef.current = null;
|
|
2032
2064
|
};
|
|
2033
2065
|
const hideNow = () => {
|
|
2034
2066
|
clearShowTimer();
|
|
@@ -2079,6 +2111,12 @@ function Tooltip({
|
|
|
2079
2111
|
el.removeEventListener("blur", hide);
|
|
2080
2112
|
};
|
|
2081
2113
|
}, [anchorRef, placement, delay]);
|
|
2114
|
+
(0, import_react10.useEffect)(() => {
|
|
2115
|
+
if (!anchor) return;
|
|
2116
|
+
const onKey = (e) => e.key === "Escape" && hideNow();
|
|
2117
|
+
window.addEventListener("keydown", onKey);
|
|
2118
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
2119
|
+
}, [anchor]);
|
|
2082
2120
|
(0, import_react10.useLayoutEffect)(() => {
|
|
2083
2121
|
if (!anchor) return;
|
|
2084
2122
|
const el = boxRef.current;
|
|
@@ -2142,9 +2180,11 @@ function Tooltip({
|
|
|
2142
2180
|
className,
|
|
2143
2181
|
onMouseEnter: show,
|
|
2144
2182
|
onMouseLeave: hide,
|
|
2145
|
-
onFocus:
|
|
2183
|
+
onFocus: (e) => {
|
|
2184
|
+
describedRef.current = e.target;
|
|
2185
|
+
show();
|
|
2186
|
+
},
|
|
2146
2187
|
onBlur: hide,
|
|
2147
|
-
"aria-describedby": anchor ? id : void 0,
|
|
2148
2188
|
children: [
|
|
2149
2189
|
children,
|
|
2150
2190
|
floating
|
|
@@ -2839,7 +2879,7 @@ var import_class_variance_authority = require("class-variance-authority");
|
|
|
2839
2879
|
var import_lucide_react16 = require("lucide-react");
|
|
2840
2880
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2841
2881
|
var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
2842
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-control transition-all duration-(--mr-motion-duration-interactive) ease-interactive disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-
|
|
2882
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-control transition-all duration-(--mr-motion-duration-interactive) ease-interactive disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
2843
2883
|
{
|
|
2844
2884
|
variants: {
|
|
2845
2885
|
variant: {
|
|
@@ -2955,11 +2995,38 @@ function NameListModal({
|
|
|
2955
2995
|
() => Object.fromEntries((options ?? []).map((o) => [o.key, !!o.initial]))
|
|
2956
2996
|
);
|
|
2957
2997
|
const toggle = (key) => setChecked((c) => ({ ...c, [key]: !c[key] }));
|
|
2998
|
+
const dialogRef = (0, import_react14.useRef)(null);
|
|
2999
|
+
const titleId = (0, import_react14.useId)();
|
|
3000
|
+
const fieldId = (0, import_react14.useId)();
|
|
2958
3001
|
(0, import_react14.useEffect)(() => {
|
|
2959
3002
|
const onKey = (e) => e.key === "Escape" && onCancel();
|
|
2960
3003
|
window.addEventListener("keydown", onKey);
|
|
2961
3004
|
return () => window.removeEventListener("keydown", onKey);
|
|
2962
3005
|
}, [onCancel]);
|
|
3006
|
+
const [opener] = (0, import_react14.useState)(() => typeof document === "undefined" ? null : document.activeElement);
|
|
3007
|
+
(0, import_react14.useEffect)(
|
|
3008
|
+
() => () => {
|
|
3009
|
+
const active = document.activeElement;
|
|
3010
|
+
if (!active || active === document.body) opener?.focus?.();
|
|
3011
|
+
},
|
|
3012
|
+
[opener]
|
|
3013
|
+
);
|
|
3014
|
+
const trapTab = (e) => {
|
|
3015
|
+
if (e.key !== "Tab" || !dialogRef.current) return;
|
|
3016
|
+
const items = [
|
|
3017
|
+
...dialogRef.current.querySelectorAll("button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex='-1'])")
|
|
3018
|
+
];
|
|
3019
|
+
if (items.length === 0) return;
|
|
3020
|
+
const first = items[0];
|
|
3021
|
+
const last = items[items.length - 1];
|
|
3022
|
+
if (e.shiftKey && document.activeElement === first) {
|
|
3023
|
+
e.preventDefault();
|
|
3024
|
+
last.focus();
|
|
3025
|
+
} else if (!e.shiftKey && document.activeElement === last) {
|
|
3026
|
+
e.preventDefault();
|
|
3027
|
+
first.focus();
|
|
3028
|
+
}
|
|
3029
|
+
};
|
|
2963
3030
|
return (0, import_react_dom5.createPortal)(
|
|
2964
3031
|
// bg-scrim, not a literal: design-tokens gained a scrim token in 2.5.0.
|
|
2965
3032
|
// No in-data-[theme=dark] override needed any more -- the token redefines
|
|
@@ -2972,18 +3039,20 @@ function NameListModal({
|
|
|
2972
3039
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
2973
3040
|
"div",
|
|
2974
3041
|
{
|
|
3042
|
+
ref: dialogRef,
|
|
2975
3043
|
role: "dialog",
|
|
2976
3044
|
"aria-modal": "true",
|
|
2977
|
-
"aria-
|
|
3045
|
+
"aria-labelledby": titleId,
|
|
3046
|
+
onKeyDown: trapTab,
|
|
2978
3047
|
className: "w-full max-w-[420px] rounded-card border border-border-default bg-surface p-5 shadow-overlay",
|
|
2979
3048
|
children: [
|
|
2980
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { className: "text-[16px] font-semibold text-text-primary", children: title }),
|
|
3049
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { id: titleId, className: "text-[16px] font-semibold text-text-primary", children: title }),
|
|
2981
3050
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "mt-4 flex flex-col gap-1.5", children: [
|
|
2982
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("label", { htmlFor:
|
|
3051
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("label", { htmlFor: fieldId, className: "text-[12px] font-medium text-text-secondary", children: fieldLabel }),
|
|
2983
3052
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2984
3053
|
"input",
|
|
2985
3054
|
{
|
|
2986
|
-
id:
|
|
3055
|
+
id: fieldId,
|
|
2987
3056
|
autoFocus: true,
|
|
2988
3057
|
value: name,
|
|
2989
3058
|
onChange: (e) => setName(e.target.value),
|
|
@@ -3141,7 +3210,7 @@ function SortButton({
|
|
|
3141
3210
|
// subtly tighter than the fixed headers next to them. A control
|
|
3142
3211
|
// should carry exactly the properties that do not inherit, and
|
|
3143
3212
|
// nothing more.
|
|
3144
|
-
"group inline-flex items-center gap-1 uppercase transition-colors",
|
|
3213
|
+
"group inline-flex items-center gap-1 uppercase transition-colors focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
3145
3214
|
ALIGN[align],
|
|
3146
3215
|
!disabled && "hover:text-text-primary"
|
|
3147
3216
|
),
|