@mediaradar/design-components 0.18.1 → 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 +89 -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 +101 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
"use strict";
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -84,6 +85,17 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
84
85
|
const [open, setOpen] = (0, import_react.useState)(false);
|
|
85
86
|
const [pos, setPos] = (0, import_react.useState)(null);
|
|
86
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, []);
|
|
87
99
|
(0, import_react.useEffect)(() => {
|
|
88
100
|
if (!open) return;
|
|
89
101
|
const onDown = (e) => {
|
|
@@ -105,6 +117,7 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
105
117
|
setPos({ top: r.bottom + 6, left, width });
|
|
106
118
|
};
|
|
107
119
|
const show = () => {
|
|
120
|
+
cancelClose();
|
|
108
121
|
place();
|
|
109
122
|
setOpen(true);
|
|
110
123
|
};
|
|
@@ -115,7 +128,7 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
115
128
|
};
|
|
116
129
|
const hoverProps = trigger === "hover" ? {
|
|
117
130
|
onMouseEnter: show,
|
|
118
|
-
onMouseLeave:
|
|
131
|
+
onMouseLeave: closeSoon,
|
|
119
132
|
onFocus: show,
|
|
120
133
|
onBlur: () => setOpen(false)
|
|
121
134
|
} : {};
|
|
@@ -128,16 +141,20 @@ function InfoTip({ text, size = 11, label = "More information", trigger = "click
|
|
|
128
141
|
onClick: toggle,
|
|
129
142
|
"aria-label": label,
|
|
130
143
|
"aria-expanded": open,
|
|
144
|
+
"aria-describedby": textId,
|
|
131
145
|
...hoverProps,
|
|
132
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",
|
|
133
147
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Info, { size, "aria-hidden": "true" })
|
|
134
148
|
}
|
|
135
149
|
),
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { id: textId, hidden: true, children: text }),
|
|
136
151
|
open && pos && (0, import_react_dom.createPortal)(
|
|
137
152
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
138
153
|
"div",
|
|
139
154
|
{
|
|
140
|
-
|
|
155
|
+
"aria-hidden": "true",
|
|
156
|
+
onMouseEnter: trigger === "hover" ? cancelClose : void 0,
|
|
157
|
+
onMouseLeave: trigger === "hover" ? closeSoon : void 0,
|
|
141
158
|
style: { position: "fixed", top: pos.top, left: pos.left, width: pos.width },
|
|
142
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",
|
|
143
160
|
children: text
|
|
@@ -586,7 +603,7 @@ var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
|
586
603
|
function boxClass(on, disabled) {
|
|
587
604
|
return cn(
|
|
588
605
|
"flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
|
|
589
|
-
on ? "border-transparent bg-brand-primaryAction text-
|
|
606
|
+
on ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input",
|
|
590
607
|
disabled && "cursor-not-allowed opacity-50"
|
|
591
608
|
);
|
|
592
609
|
}
|
|
@@ -926,7 +943,7 @@ function DateRangeFilter({
|
|
|
926
943
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
927
944
|
"span",
|
|
928
945
|
{
|
|
929
|
-
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"}`,
|
|
930
947
|
children: d.getDate()
|
|
931
948
|
}
|
|
932
949
|
)
|
|
@@ -937,7 +954,7 @@ function DateRangeFilter({
|
|
|
937
954
|
}) }),
|
|
938
955
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mt-4 flex justify-end gap-2", children: [
|
|
939
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" }),
|
|
940
|
-
/* @__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" })
|
|
941
958
|
] })
|
|
942
959
|
] })
|
|
943
960
|
]
|
|
@@ -1217,6 +1234,7 @@ function RadioOption({
|
|
|
1217
1234
|
}
|
|
1218
1235
|
function RowInfoTip({ text }) {
|
|
1219
1236
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1237
|
+
const id = (0, import_react4.useId)();
|
|
1220
1238
|
const ref = (0, import_react4.useRef)(null);
|
|
1221
1239
|
(0, import_react4.useEffect)(() => {
|
|
1222
1240
|
if (!open) return;
|
|
@@ -1237,14 +1255,16 @@ function RowInfoTip({ text }) {
|
|
|
1237
1255
|
},
|
|
1238
1256
|
"aria-label": "More information",
|
|
1239
1257
|
"aria-expanded": open,
|
|
1240
|
-
|
|
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",
|
|
1241
1260
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react7.AlertCircle, { size: 13, "aria-hidden": "true" })
|
|
1242
1261
|
}
|
|
1243
1262
|
),
|
|
1244
|
-
|
|
1263
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1245
1264
|
"span",
|
|
1246
1265
|
{
|
|
1247
|
-
|
|
1266
|
+
id,
|
|
1267
|
+
hidden: !open,
|
|
1248
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",
|
|
1249
1269
|
children: text
|
|
1250
1270
|
}
|
|
@@ -1596,7 +1616,7 @@ var NO_RESULTS_BODY = "Your filters may be too narrow, conflict with each other,
|
|
|
1596
1616
|
function noResultsBody(workspaceName) {
|
|
1597
1617
|
return workspaceName ? `Nothing in the \u201C${workspaceName}\u201D workspace matches. ${NO_RESULTS_BODY}` : NO_RESULTS_BODY;
|
|
1598
1618
|
}
|
|
1599
|
-
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";
|
|
1600
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";
|
|
1601
1621
|
function NoResultsEmptyState({
|
|
1602
1622
|
title = NO_RESULTS_TITLE,
|
|
@@ -1937,6 +1957,15 @@ var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
|
1937
1957
|
function cx6(...parts) {
|
|
1938
1958
|
return parts.filter(Boolean).join(" ");
|
|
1939
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
|
+
}
|
|
1940
1969
|
function exitDurationMs(el) {
|
|
1941
1970
|
if (typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return 0;
|
|
1942
1971
|
const cs = window.getComputedStyle(el);
|
|
@@ -1974,6 +2003,7 @@ function Tooltip({
|
|
|
1974
2003
|
const openRef = (0, import_react10.useRef)(false);
|
|
1975
2004
|
const mountedRef = (0, import_react10.useRef)(false);
|
|
1976
2005
|
const id = (0, import_react10.useId)();
|
|
2006
|
+
const describedRef = (0, import_react10.useRef)(null);
|
|
1977
2007
|
const clearHideTimer = () => {
|
|
1978
2008
|
if (hideTimer.current) {
|
|
1979
2009
|
clearTimeout(hideTimer.current);
|
|
@@ -2010,7 +2040,8 @@ function Tooltip({
|
|
|
2010
2040
|
if (!mountedRef.current) setBoxWidth(null);
|
|
2011
2041
|
mountedRef.current = true;
|
|
2012
2042
|
setAnchor({ top: r.top, left: r.left, width: r.width, height: r.height, bottom: r.bottom, right: r.right });
|
|
2013
|
-
|
|
2043
|
+
const target = anchorRef ? el : describedRef.current;
|
|
2044
|
+
if (target) addDescribedBy(target, id);
|
|
2014
2045
|
};
|
|
2015
2046
|
const show = () => {
|
|
2016
2047
|
clearHideTimer();
|
|
@@ -2027,7 +2058,9 @@ function Tooltip({
|
|
|
2027
2058
|
mountedRef.current = false;
|
|
2028
2059
|
setAnchor(null);
|
|
2029
2060
|
setBoxWidth(null);
|
|
2030
|
-
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;
|
|
2031
2064
|
};
|
|
2032
2065
|
const hideNow = () => {
|
|
2033
2066
|
clearShowTimer();
|
|
@@ -2078,6 +2111,12 @@ function Tooltip({
|
|
|
2078
2111
|
el.removeEventListener("blur", hide);
|
|
2079
2112
|
};
|
|
2080
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]);
|
|
2081
2120
|
(0, import_react10.useLayoutEffect)(() => {
|
|
2082
2121
|
if (!anchor) return;
|
|
2083
2122
|
const el = boxRef.current;
|
|
@@ -2141,9 +2180,11 @@ function Tooltip({
|
|
|
2141
2180
|
className,
|
|
2142
2181
|
onMouseEnter: show,
|
|
2143
2182
|
onMouseLeave: hide,
|
|
2144
|
-
onFocus:
|
|
2183
|
+
onFocus: (e) => {
|
|
2184
|
+
describedRef.current = e.target;
|
|
2185
|
+
show();
|
|
2186
|
+
},
|
|
2145
2187
|
onBlur: hide,
|
|
2146
|
-
"aria-describedby": anchor ? id : void 0,
|
|
2147
2188
|
children: [
|
|
2148
2189
|
children,
|
|
2149
2190
|
floating
|
|
@@ -2838,7 +2879,7 @@ var import_class_variance_authority = require("class-variance-authority");
|
|
|
2838
2879
|
var import_lucide_react16 = require("lucide-react");
|
|
2839
2880
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2840
2881
|
var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
2841
|
-
"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",
|
|
2842
2883
|
{
|
|
2843
2884
|
variants: {
|
|
2844
2885
|
variant: {
|
|
@@ -2954,11 +2995,38 @@ function NameListModal({
|
|
|
2954
2995
|
() => Object.fromEntries((options ?? []).map((o) => [o.key, !!o.initial]))
|
|
2955
2996
|
);
|
|
2956
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)();
|
|
2957
3001
|
(0, import_react14.useEffect)(() => {
|
|
2958
3002
|
const onKey = (e) => e.key === "Escape" && onCancel();
|
|
2959
3003
|
window.addEventListener("keydown", onKey);
|
|
2960
3004
|
return () => window.removeEventListener("keydown", onKey);
|
|
2961
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
|
+
};
|
|
2962
3030
|
return (0, import_react_dom5.createPortal)(
|
|
2963
3031
|
// bg-scrim, not a literal: design-tokens gained a scrim token in 2.5.0.
|
|
2964
3032
|
// No in-data-[theme=dark] override needed any more -- the token redefines
|
|
@@ -2971,18 +3039,20 @@ function NameListModal({
|
|
|
2971
3039
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
2972
3040
|
"div",
|
|
2973
3041
|
{
|
|
3042
|
+
ref: dialogRef,
|
|
2974
3043
|
role: "dialog",
|
|
2975
3044
|
"aria-modal": "true",
|
|
2976
|
-
"aria-
|
|
3045
|
+
"aria-labelledby": titleId,
|
|
3046
|
+
onKeyDown: trapTab,
|
|
2977
3047
|
className: "w-full max-w-[420px] rounded-card border border-border-default bg-surface p-5 shadow-overlay",
|
|
2978
3048
|
children: [
|
|
2979
|
-
/* @__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 }),
|
|
2980
3050
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "mt-4 flex flex-col gap-1.5", children: [
|
|
2981
|
-
/* @__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 }),
|
|
2982
3052
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2983
3053
|
"input",
|
|
2984
3054
|
{
|
|
2985
|
-
id:
|
|
3055
|
+
id: fieldId,
|
|
2986
3056
|
autoFocus: true,
|
|
2987
3057
|
value: name,
|
|
2988
3058
|
onChange: (e) => setName(e.target.value),
|
|
@@ -3140,7 +3210,7 @@ function SortButton({
|
|
|
3140
3210
|
// subtly tighter than the fixed headers next to them. A control
|
|
3141
3211
|
// should carry exactly the properties that do not inherit, and
|
|
3142
3212
|
// nothing more.
|
|
3143
|
-
"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",
|
|
3144
3214
|
ALIGN[align],
|
|
3145
3215
|
!disabled && "hover:text-text-primary"
|
|
3146
3216
|
),
|