@mediaradar/design-components 0.13.0 → 0.15.0
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 +96 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -12
- package/dist/index.d.ts +50 -12
- package/dist/index.js +275 -205
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -517,17 +517,22 @@ var TONE_STYLE = {
|
|
|
517
517
|
}
|
|
518
518
|
};
|
|
519
519
|
var KIND = {
|
|
520
|
-
|
|
520
|
+
// Twice the vertical room the first version had. At py-0.5 the pill hugged
|
|
521
|
+
// its text and read as a tight little tag; at py-1 it reads as a deliberate
|
|
522
|
+
// object. Taken from the status pills the product had already arrived at by
|
|
523
|
+
// hand, which were noticeably more comfortable than anything else -- the
|
|
524
|
+
// breathing room was what made them so, not their extra pixel of type.
|
|
525
|
+
label: "px-2.5 py-1",
|
|
521
526
|
// Square-ish and centred, with a floor width so a 1-digit and a 3-digit
|
|
522
527
|
// count are the same shape, and lining figures so the width does not shift
|
|
523
528
|
// as the number changes.
|
|
524
529
|
count: "h-[18px] min-w-[18px] justify-center px-1.5 tabular-nums",
|
|
525
530
|
// The only kind that shouts. Caps need the letterspacing -- caps set tight
|
|
526
531
|
// are harder to read than the sentence case they replaced.
|
|
527
|
-
eyebrow: "px-2 py-
|
|
532
|
+
eyebrow: "px-2.5 py-1 uppercase tracking-wider"
|
|
528
533
|
};
|
|
529
|
-
function Badge({ tone = "neutral", kind = "label", children, className }) {
|
|
530
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.
|
|
534
|
+
function Badge({ tone = "neutral", kind = "label", dot = false, children, className }) {
|
|
535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
531
536
|
"span",
|
|
532
537
|
{
|
|
533
538
|
style: TONE_STYLE[tone],
|
|
@@ -541,7 +546,10 @@ function Badge({ tone = "neutral", kind = "label", children, className }) {
|
|
|
541
546
|
KIND[kind],
|
|
542
547
|
className
|
|
543
548
|
),
|
|
544
|
-
children
|
|
549
|
+
children: [
|
|
550
|
+
dot && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": "true", className: "size-1.5 shrink-0 rounded-full bg-current" }),
|
|
551
|
+
children
|
|
552
|
+
]
|
|
545
553
|
}
|
|
546
554
|
);
|
|
547
555
|
}
|
|
@@ -1903,6 +1911,19 @@ var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
|
1903
1911
|
function cx6(...parts) {
|
|
1904
1912
|
return parts.filter(Boolean).join(" ");
|
|
1905
1913
|
}
|
|
1914
|
+
function exitDurationMs(el) {
|
|
1915
|
+
if (typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return 0;
|
|
1916
|
+
const cs = window.getComputedStyle(el);
|
|
1917
|
+
if (cs.transitionProperty === "none") return 0;
|
|
1918
|
+
const toMs = (v) => {
|
|
1919
|
+
const n = parseFloat(v);
|
|
1920
|
+
if (!Number.isFinite(n)) return 0;
|
|
1921
|
+
return v.trim().endsWith("ms") ? n : n * 1e3;
|
|
1922
|
+
};
|
|
1923
|
+
const durations = cs.transitionDuration.split(",").map(toMs);
|
|
1924
|
+
const delays = cs.transitionDelay.split(",").map(toMs);
|
|
1925
|
+
return Math.max(0, ...durations.map((d, i) => d + (delays[i] ?? delays[0] ?? 0)));
|
|
1926
|
+
}
|
|
1906
1927
|
function Tooltip({
|
|
1907
1928
|
label,
|
|
1908
1929
|
children,
|
|
@@ -1922,6 +1943,10 @@ function Tooltip({
|
|
|
1922
1943
|
const boxRef = (0, import_react10.useRef)(null);
|
|
1923
1944
|
const hideTimer = (0, import_react10.useRef)(null);
|
|
1924
1945
|
const showTimer = (0, import_react10.useRef)(null);
|
|
1946
|
+
const exitTimer = (0, import_react10.useRef)(null);
|
|
1947
|
+
const [shown, setShown] = (0, import_react10.useState)(false);
|
|
1948
|
+
const openRef = (0, import_react10.useRef)(false);
|
|
1949
|
+
const mountedRef = (0, import_react10.useRef)(false);
|
|
1925
1950
|
const id = (0, import_react10.useId)();
|
|
1926
1951
|
const clearHideTimer = () => {
|
|
1927
1952
|
if (hideTimer.current) {
|
|
@@ -1935,10 +1960,17 @@ function Tooltip({
|
|
|
1935
1960
|
showTimer.current = null;
|
|
1936
1961
|
}
|
|
1937
1962
|
};
|
|
1963
|
+
const clearExitTimer = () => {
|
|
1964
|
+
if (exitTimer.current) {
|
|
1965
|
+
clearTimeout(exitTimer.current);
|
|
1966
|
+
exitTimer.current = null;
|
|
1967
|
+
}
|
|
1968
|
+
};
|
|
1938
1969
|
(0, import_react10.useEffect)(
|
|
1939
1970
|
() => () => {
|
|
1940
1971
|
clearHideTimer();
|
|
1941
1972
|
clearShowTimer();
|
|
1973
|
+
clearExitTimer();
|
|
1942
1974
|
},
|
|
1943
1975
|
[]
|
|
1944
1976
|
);
|
|
@@ -1946,26 +1978,56 @@ function Tooltip({
|
|
|
1946
1978
|
const el = anchorRef ? anchorRef.current : ref.current;
|
|
1947
1979
|
if (!el) return;
|
|
1948
1980
|
if (whenTruncated && el.scrollWidth <= el.clientWidth) return;
|
|
1981
|
+
clearExitTimer();
|
|
1982
|
+
openRef.current = true;
|
|
1949
1983
|
const r = el.getBoundingClientRect();
|
|
1950
|
-
setBoxWidth(null);
|
|
1984
|
+
if (!mountedRef.current) setBoxWidth(null);
|
|
1985
|
+
mountedRef.current = true;
|
|
1951
1986
|
setAnchor({ top: r.top, left: r.left, width: r.width, height: r.height, bottom: r.bottom, right: r.right });
|
|
1952
1987
|
if (anchorRef) el.setAttribute("aria-describedby", id);
|
|
1953
1988
|
};
|
|
1954
1989
|
const show = () => {
|
|
1955
1990
|
clearHideTimer();
|
|
1956
|
-
|
|
1991
|
+
clearShowTimer();
|
|
1992
|
+
if (delay > 0 && !mountedRef.current) {
|
|
1957
1993
|
showTimer.current = setTimeout(reveal, delay);
|
|
1958
1994
|
} else {
|
|
1959
1995
|
reveal();
|
|
1960
1996
|
}
|
|
1961
1997
|
};
|
|
1962
|
-
const
|
|
1963
|
-
|
|
1964
|
-
|
|
1998
|
+
const unmount = () => {
|
|
1999
|
+
clearExitTimer();
|
|
2000
|
+
if (openRef.current || !mountedRef.current) return;
|
|
2001
|
+
mountedRef.current = false;
|
|
1965
2002
|
setAnchor(null);
|
|
1966
2003
|
setBoxWidth(null);
|
|
1967
2004
|
if (anchorRef?.current) anchorRef.current.removeAttribute("aria-describedby");
|
|
1968
2005
|
};
|
|
2006
|
+
const hideNow = () => {
|
|
2007
|
+
clearShowTimer();
|
|
2008
|
+
clearHideTimer();
|
|
2009
|
+
openRef.current = false;
|
|
2010
|
+
if (!mountedRef.current) return;
|
|
2011
|
+
setShown(false);
|
|
2012
|
+
clearExitTimer();
|
|
2013
|
+
const ms = boxRef.current ? exitDurationMs(boxRef.current) : 0;
|
|
2014
|
+
if (ms === 0) {
|
|
2015
|
+
unmount();
|
|
2016
|
+
return;
|
|
2017
|
+
}
|
|
2018
|
+
exitTimer.current = setTimeout(unmount, ms + 50);
|
|
2019
|
+
};
|
|
2020
|
+
const keepOpen = () => {
|
|
2021
|
+
clearHideTimer();
|
|
2022
|
+
if (openRef.current || !mountedRef.current) return;
|
|
2023
|
+
clearExitTimer();
|
|
2024
|
+
openRef.current = true;
|
|
2025
|
+
setShown(true);
|
|
2026
|
+
};
|
|
2027
|
+
const onBoxTransitionEnd = (e) => {
|
|
2028
|
+
if (e.target !== e.currentTarget || e.propertyName !== "opacity") return;
|
|
2029
|
+
if (!openRef.current) unmount();
|
|
2030
|
+
};
|
|
1969
2031
|
const hide = () => {
|
|
1970
2032
|
clearShowTimer();
|
|
1971
2033
|
if (!interactive) {
|
|
@@ -1995,6 +2057,7 @@ function Tooltip({
|
|
|
1995
2057
|
const el = boxRef.current;
|
|
1996
2058
|
if (!el) return;
|
|
1997
2059
|
setBoxWidth(el.getBoundingClientRect().width);
|
|
2060
|
+
if (openRef.current) setShown(true);
|
|
1998
2061
|
}, [anchor, label]);
|
|
1999
2062
|
const margin = 8;
|
|
2000
2063
|
let style = { top: 0, left: 0 };
|
|
@@ -2022,10 +2085,19 @@ function Tooltip({
|
|
|
2022
2085
|
id,
|
|
2023
2086
|
"data-testid": testIdPrefix && `${testIdPrefix}-tooltip`,
|
|
2024
2087
|
style: { top: style.top, left: style.left, right: style.right, visibility: boxWidth == null ? "hidden" : "visible" },
|
|
2025
|
-
onMouseEnter: interactive ?
|
|
2088
|
+
onMouseEnter: interactive ? keepOpen : void 0,
|
|
2026
2089
|
onMouseLeave: interactive ? hide : void 0,
|
|
2090
|
+
onTransitionEnd: onBoxTransitionEnd,
|
|
2027
2091
|
className: cx6(
|
|
2028
2092
|
"fixed z-[90] w-max max-w-xs whitespace-normal break-words px-2.5 py-1.5 text-xs leading-snug",
|
|
2093
|
+
// Fade in/out. The sys duration token rather than a ref one:
|
|
2094
|
+
// it is what Button's hover/press transition uses, and a
|
|
2095
|
+
// tooltip's fade is the same kind of interactive feedback.
|
|
2096
|
+
// design-tokens has no in-out curve (ease-interactive is the
|
|
2097
|
+
// decelerating "standard" curve), so ease-in-out is Tailwind's.
|
|
2098
|
+
"transition-opacity duration-(--mr-motion-duration-interactive) ease-in-out motion-reduce:transition-none",
|
|
2099
|
+
shown ? "opacity-100" : "opacity-0",
|
|
2100
|
+
// Non-interactive: never a pointer target, fade-out included.
|
|
2029
2101
|
interactive ? "pointer-events-auto" : "pointer-events-none",
|
|
2030
2102
|
variant === "inverted" ? "rounded-control bg-text-primary text-surface" : "rounded-control border border-border-default bg-surface text-text-primary shadow-overlay",
|
|
2031
2103
|
translate
|
|
@@ -2765,21 +2837,19 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
2765
2837
|
);
|
|
2766
2838
|
var Button = (0, import_react13.forwardRef)(
|
|
2767
2839
|
({ className, variant, size, asChild = false, loading = false, disabled, children, ...props }, ref) => {
|
|
2768
|
-
const
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
}
|
|
2782
|
-
);
|
|
2840
|
+
const shared = {
|
|
2841
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
2842
|
+
disabled: disabled || loading,
|
|
2843
|
+
"aria-busy": loading || void 0,
|
|
2844
|
+
...props
|
|
2845
|
+
};
|
|
2846
|
+
if (asChild) {
|
|
2847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_slot.Slot, { ref, ...shared, children });
|
|
2848
|
+
}
|
|
2849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("button", { ref, ...shared, children: [
|
|
2850
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react15.Loader2, { className: "size-4 shrink-0 animate-spin", "aria-hidden": "true" }),
|
|
2851
|
+
children
|
|
2852
|
+
] });
|
|
2783
2853
|
}
|
|
2784
2854
|
);
|
|
2785
2855
|
Button.displayName = "Button";
|