@stackone/malachite 2.53.0 → 2.55.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.
@@ -1,84 +1,86 @@
1
- import { jsx as f, jsxs as N, Fragment as te } from "react/jsx-runtime";
2
- import S, { useState as v, useRef as c, useCallback as ne, useId as re, useEffect as w, useInsertionEffect as oe } from "react";
3
- import { createPortal as ie } from "react-dom";
4
- import { ensureOverlayStyles as ae, overlayIdentity as se } from "./portalOverlay.js";
5
- import { useTopLayer as le } from "./topLayer.js";
6
- const ce = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), fe = (n) => n.split(ce).map((s, y) => /* @__PURE__ */ N(S.Fragment, { children: [
7
- s,
1
+ import { jsx as f, jsxs as Y, Fragment as oe } from "react/jsx-runtime";
2
+ import $, { useState as b, useRef as d, useCallback as ie, useId as ae, useEffect as g, useInsertionEffect as se } from "react";
3
+ import { createPortal as le } from "react-dom";
4
+ import { FOCUS_RING as ce } from "./focusRing.js";
5
+ import { ensureOverlayStyles as de, overlayIdentity as fe } from "./portalOverlay.js";
6
+ import { useTopLayer as ue } from "./topLayer.js";
7
+ const me = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), pe = (n) => n.split(me).map((a, w) => /* @__PURE__ */ Y($.Fragment, { children: [
8
+ a,
8
9
  /* @__PURE__ */ f("wbr", {})
9
- ] }, y)), ue = {
10
+ ] }, w)), he = {
10
11
  minWidth: 0,
11
12
  overflow: "hidden"
12
- }, k = {
13
+ }, z = {
13
14
  flex: 1,
14
15
  minWidth: 0
15
- }, z = 8, we = ({
16
+ }, U = 8, Ee = ({
16
17
  text: n,
17
- children: s,
18
- delay: y = 1,
19
- wrapChildren: Y = !1,
18
+ children: a,
19
+ delay: w = 1,
20
+ wrapChildren: G = !1,
20
21
  triggerAs: O = "div",
21
- inline: T = !1,
22
- placement: U = "top",
23
- isShrinkable: I = !1,
24
- maxWidth: b = "320px",
25
- fill: x = !1,
22
+ inline: A = !1,
23
+ placement: q = "top",
24
+ isShrinkable: B = !1,
25
+ maxWidth: x = "320px",
26
+ fill: E = !1,
26
27
  shouldShow: u,
27
- suppressed: o = !1,
28
- describesTrigger: A = !0,
29
- showOnFocus: d = !0
28
+ suppressed: r = !1,
29
+ describesTrigger: F = !0,
30
+ showOnFocus: c = !0,
31
+ focusableTrigger: m = !1
30
32
  }) => {
31
- const q = I || x ? { ...I ? ue : {}, ...x ? k : {} } : void 0, [t, m] = v(!1), [p, G] = v(!1), h = c(null), a = c(null), r = ne(() => {
32
- h.current && (clearTimeout(h.current), h.current = null), a.current !== null && (cancelAnimationFrame(a.current), a.current = null);
33
- }, []), B = () => {
34
- G(!0), a.current !== null && cancelAnimationFrame(a.current), a.current = requestAnimationFrame(() => {
35
- a.current = null, m(!0);
33
+ const K = B || E ? { ...B ? he : {}, ...E ? z : {} } : void 0, [t, p] = b(!1), [h, X] = b(m), v = d(null), s = d(null), o = ie(() => {
34
+ v.current && (clearTimeout(v.current), v.current = null), s.current !== null && (cancelAnimationFrame(s.current), s.current = null);
35
+ }, []), T = () => {
36
+ X(!0), s.current !== null && cancelAnimationFrame(s.current), s.current = requestAnimationFrame(() => {
37
+ s.current = null, p(!0);
36
38
  });
37
- }, E = c(null), g = c(null);
38
- le(E, t);
39
- const F = re(), l = n != null && n !== "" && n !== !1, K = (e) => {
40
- e.stopPropagation(), !(!l || o || u && !u()) && (r(), h.current = setTimeout(() => {
41
- B();
42
- }, y * 1e3));
43
- }, X = (e) => {
44
- e.stopPropagation(), r(), m(!1);
45
- }, W = () => {
46
- !d || !l || o || u && !u() || (r(), B());
47
- }, D = () => {
48
- r(), m(!1);
49
- }, M = c(d);
50
- w(() => {
39
+ }, R = d(null), y = d(null);
40
+ ue(R, t);
41
+ const W = ae(), l = n != null && n !== "" && n !== !1, D = (e) => {
42
+ e.stopPropagation(), !(!l || r || u && !u()) && (o(), v.current = setTimeout(() => {
43
+ T();
44
+ }, w * 1e3));
45
+ }, J = (e) => {
46
+ e.stopPropagation(), o(), p(!1);
47
+ }, _ = () => {
48
+ !c || !l || r || u && !u() || (o(), T());
49
+ }, Q = () => {
50
+ o(), p(!1);
51
+ }, M = d(c);
52
+ g(() => {
51
53
  var i;
52
- const e = d && !M.current;
53
- M.current = d, e && ((i = g.current) != null && i.matches(":focus-within")) && W();
54
+ const e = c && !M.current;
55
+ M.current = c, e && ((i = y.current) != null && i.matches(":focus-within")) && _();
54
56
  });
55
- const [J, Q] = v(o);
56
- o !== J && (Q(o), o && m(!1)), w(() => {
57
- o && r();
58
- }, [o, r]);
59
- const [, _] = v({});
60
- w(() => {
57
+ const [Z, ee] = b(r);
58
+ r !== Z && (ee(r), r && p(!1)), g(() => {
59
+ r && o();
60
+ }, [r, o]);
61
+ const [, C] = b({});
62
+ g(() => {
61
63
  if (!t)
62
64
  return () => {
63
- r();
65
+ o();
64
66
  };
65
67
  const e = () => {
66
- _({});
68
+ C({});
67
69
  };
68
70
  return window.addEventListener("scroll", e, !0), window.addEventListener("resize", e), () => {
69
- r(), window.removeEventListener("scroll", e, !0), window.removeEventListener("resize", e);
71
+ o(), window.removeEventListener("scroll", e, !0), window.removeEventListener("resize", e);
70
72
  };
71
- }, [t, r]), w(() => {
72
- t && _({});
73
+ }, [t, o]), g(() => {
74
+ t && C({});
73
75
  }, [t]);
74
- const Z = () => {
75
- if (!g.current)
76
+ const te = () => {
77
+ if (!y.current)
76
78
  return { display: "none" };
77
- const e = g.current.getBoundingClientRect(), i = {
79
+ const e = y.current.getBoundingClientRect(), i = {
78
80
  position: "fixed",
79
81
  display: "flex",
80
82
  width: "max-content",
81
- maxWidth: typeof b == "number" ? `${b}px` : b,
83
+ maxWidth: typeof x == "number" ? `${x}px` : x,
82
84
  minWidth: "32px",
83
85
  minHeight: "32px",
84
86
  padding: "8px 12px",
@@ -96,27 +98,27 @@ const ce = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), fe = (n) => n.split(ce).map((s
96
98
  opacity: t ? 1 : 0,
97
99
  visibility: t ? "visible" : "hidden",
98
100
  transition: "opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out"
99
- }, R = () => {
100
- var j;
101
- const L = e.left + e.width / 2, P = ((j = E.current) == null ? void 0 : j.getBoundingClientRect().width) ?? 0;
102
- if (P === 0)
103
- return L;
104
- const C = P / 2, V = z + C, H = window.innerWidth - z - C;
105
- return V > H ? L : Math.min(Math.max(L, V), H);
101
+ }, L = () => {
102
+ var k;
103
+ const I = e.left + e.width / 2, V = ((k = R.current) == null ? void 0 : k.getBoundingClientRect().width) ?? 0;
104
+ if (V === 0)
105
+ return I;
106
+ const H = V / 2, N = U + H, j = window.innerWidth - U - H;
107
+ return N > j ? I : Math.min(Math.max(I, N), j);
106
108
  };
107
- switch (U) {
109
+ switch (q) {
108
110
  case "top":
109
111
  return {
110
112
  ...i,
111
113
  top: e.top - 8,
112
- left: R(),
114
+ left: L(),
113
115
  transform: `translate(-50%, -100%) ${t ? "scale(1)" : "scale(0.95)"}`
114
116
  };
115
117
  case "bottom":
116
118
  return {
117
119
  ...i,
118
120
  top: e.bottom + 8,
119
- left: R(),
121
+ left: L(),
120
122
  transform: `translateX(-50%) ${t ? "scale(1)" : "scale(0.95)"}`
121
123
  };
122
124
  case "left":
@@ -137,41 +139,43 @@ const ce = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), fe = (n) => n.split(ce).map((s
137
139
  return {
138
140
  ...i,
139
141
  top: e.top - 8,
140
- left: R(),
142
+ left: L(),
141
143
  transform: `translate(-50%, -100%) ${t ? "scale(1)" : "scale(0.95)"}`
142
144
  };
143
145
  }
144
- }, $ = l && p && A ? F : void 0;
145
- oe(() => {
146
- l && p && ae();
147
- }, [l, p]);
148
- const ee = Y || !S.isValidElement(s) ? /* @__PURE__ */ f("span", { "aria-describedby": $, style: x ? k : void 0, children: s }) : S.cloneElement(s, {
149
- "aria-describedby": [s.props["aria-describedby"], $].filter(Boolean).join(" ") || void 0
150
- });
151
- return /* @__PURE__ */ N(te, { children: [
146
+ }, S = l && h && F ? W : void 0;
147
+ se(() => {
148
+ l && h && de();
149
+ }, [l, h]);
150
+ const ne = m ? a : G || !$.isValidElement(a) ? /* @__PURE__ */ f("span", { "aria-describedby": S, style: E ? z : void 0, children: a }) : $.cloneElement(a, {
151
+ "aria-describedby": [a.props["aria-describedby"], S].filter(Boolean).join(" ") || void 0
152
+ }), re = A ? "span" : O, P = m && l && !r && c;
153
+ return /* @__PURE__ */ Y(oe, { children: [
152
154
  /* @__PURE__ */ f(
153
- T ? "span" : O,
155
+ re,
154
156
  {
155
- ref: g,
156
- className: `relative ${T ? "inline-flex max-w-full align-middle" : "flex"} items-center`,
157
- style: q,
158
- onMouseEnter: K,
159
- onMouseLeave: X,
160
- onFocus: W,
161
- onBlur: D,
162
- children: ee
157
+ ref: y,
158
+ className: `relative ${A ? "inline-flex max-w-full align-middle" : "flex"} items-center${P ? ` ${ce}` : ""}`,
159
+ style: K,
160
+ tabIndex: P ? 0 : void 0,
161
+ "aria-describedby": m ? S : void 0,
162
+ onMouseEnter: D,
163
+ onMouseLeave: J,
164
+ onFocus: _,
165
+ onBlur: Q,
166
+ children: ne
163
167
  }
164
168
  ),
165
- l && p && ie(
169
+ l && h && le(
166
170
  /* @__PURE__ */ f(
167
171
  "div",
168
172
  {
169
- ref: E,
170
- id: F,
173
+ ref: R,
174
+ id: W,
171
175
  role: "tooltip",
172
- "aria-hidden": A ? void 0 : !0,
173
- ...se("tooltip"),
174
- style: Z(),
176
+ "aria-hidden": F ? void 0 : !0,
177
+ ...fe("tooltip"),
178
+ style: te(),
175
179
  children: /* @__PURE__ */ f(
176
180
  "span",
177
181
  {
@@ -179,7 +183,7 @@ const ce = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), fe = (n) => n.split(ce).map((s
179
183
  minWidth: 0,
180
184
  overflowWrap: "anywhere"
181
185
  },
182
- children: typeof n == "string" ? fe(n) : n
186
+ children: typeof n == "string" ? pe(n) : n
183
187
  }
184
188
  )
185
189
  }
@@ -189,6 +193,6 @@ const ce = new RegExp("(?<=[/\\\\.\\-_?&#=:@])"), fe = (n) => n.split(ce).map((s
189
193
  ] });
190
194
  };
191
195
  export {
192
- we as default
196
+ Ee as default
193
197
  };
194
198
  //# sourceMappingURL=Tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId, useInsertionEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ensureOverlayStyles, overlayIdentity } from './portalOverlay';\nimport { useTopLayer } from './topLayer';\n\n// Split after each delimiter so long values (URLs, dotted paths) wrap at \"/\" or \".\"\n// instead of mid-token. <wbr> is copy-safe (a zero-width space would corrupt a copied\n// URL); overflow-wrap still handles a single run too long to fit.\nconst WRAP_AFTER = /(?<=[/\\\\.\\-_?&#=:@])/;\nconst withBreakOpportunities = (value: string): React.ReactNode =>\n value.split(WRAP_AFTER).map((chunk, i) => (\n <React.Fragment key={i}>\n {chunk}\n <wbr />\n </React.Fragment>\n ));\n\ninterface TooltipProps {\n text: React.ReactNode | string;\n children: React.ReactNode;\n delay?: number;\n wrapChildren?: boolean;\n placement?: 'top' | 'bottom' | 'left' | 'right';\n isShrinkable?: boolean;\n fill?: boolean;\n /** Max width of tooltip. Default: 320px */\n maxWidth?: number | string;\n /** Called synchronously when the trigger is hovered/focused; return false to\n * suppress the tooltip for this interaction. Lets wrappers defer expensive\n * checks (e.g. truncation measurement) to interaction time instead of mount. */\n shouldShow?: () => boolean;\n suppressed?: boolean;\n triggerAs?: 'div' | 'span';\n inline?: boolean;\n /** Whether the tooltip acts as the trigger's accessible description. False where the\n * trigger already points at the same sentence on screen, so it is not announced twice. */\n describesTrigger?: boolean;\n /** False to open on hover only, e.g. where script moves focus onto the trigger. */\n showOnFocus?: boolean;\n}\n\nconst SHRINKABLE_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n};\n\nconst FILL_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\n/** Kept clear of the viewport edge so a clamped tooltip does not sit flush against it. */\nconst VIEWPORT_MARGIN = 8;\n\nconst Tooltip: React.FC<TooltipProps> = ({\n text,\n children,\n delay = 1,\n wrapChildren = false,\n triggerAs = 'div',\n inline = false,\n placement = 'top',\n isShrinkable = false,\n maxWidth = '320px',\n fill = false,\n shouldShow,\n suppressed = false,\n describesTrigger = true,\n showOnFocus = true,\n}) => {\n const triggerStyle =\n isShrinkable || fill\n ? { ...(isShrinkable ? SHRINKABLE_STYLE : {}), ...(fill ? FILL_STYLE : {}) }\n : undefined;\n\n const [isVisible, setIsVisible] = useState(false);\n // Portal mounts on first show, not on mount: an at-rest tooltip otherwise\n // costs a hidden document.body node plus a getBoundingClientRect per render —\n // multiplied by every row in a large table.\n const [hasShown, setHasShown] = useState(false);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showFrameRef = useRef<number | null>(null);\n\n const cancelPendingShow = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n showFrameRef.current = null;\n }\n }, []);\n\n const scheduleVisible = () => {\n // Two steps so the portal mounts hidden first and the fade-in transition\n // still runs on the very first show. The frame is tracked so leave/blur/\n // unmount can cancel a show that is already past its delay.\n setHasShown(true);\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n }\n showFrameRef.current = requestAnimationFrame(() => {\n showFrameRef.current = null;\n setIsVisible(true);\n });\n };\n const tooltipRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n // Tied to visibility, not mount: the node is latched into the DOM after its first show, and\n // re-entering on each show keeps a tooltip above the panel it is annotating.\n useTopLayer(tooltipRef, isVisible);\n\n const tooltipId = useId();\n\n const hasText = text !== null && text !== undefined && text !== '' && text !== false;\n\n const handleMouseEnter = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n if (!hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n\n timeoutRef.current = setTimeout(() => {\n scheduleVisible();\n }, delay * 1000);\n };\n\n const handleMouseLeave = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const handleFocus = () => {\n if (!showOnFocus || !hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n scheduleVisible();\n };\n\n const handleBlur = () => {\n cancelPendingShow();\n setIsVisible(false);\n };\n\n // Turning on while the trigger already holds focus fires no focus event to open on.\n const showOnFocusRef = useRef(showOnFocus);\n useEffect(() => {\n const switchedOn = showOnFocus && !showOnFocusRef.current;\n showOnFocusRef.current = showOnFocus;\n if (switchedOn && triggerRef.current?.matches(':focus-within')) {\n handleFocus();\n }\n });\n\n const [wasSuppressed, setWasSuppressed] = useState(suppressed);\n if (suppressed !== wasSuppressed) {\n setWasSuppressed(suppressed);\n if (suppressed) {\n setIsVisible(false);\n }\n }\n\n useEffect(() => {\n if (suppressed) {\n cancelPendingShow();\n }\n }, [suppressed, cancelPendingShow]);\n\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n // Only a VISIBLE tooltip needs to track scroll/resize; keeping global\n // listeners per mounted instance made every scroll event fan out across\n // every tooltip on the page.\n if (!isVisible) {\n return () => {\n cancelPendingShow();\n };\n }\n const handleUpdate = () => {\n forceUpdate({});\n };\n\n window.addEventListener('scroll', handleUpdate, true);\n window.addEventListener('resize', handleUpdate);\n\n return () => {\n cancelPendingShow();\n window.removeEventListener('scroll', handleUpdate, true);\n window.removeEventListener('resize', handleUpdate);\n };\n }, [isVisible, cancelPendingShow]);\n\n // The first render that mounts the tooltip has no measured width yet, so the clamp below\n // cannot run on it. One extra pass once it is in the DOM gives the clamp its measurement\n // — before the opacity transition finishes, so nothing is seen sliding into place.\n useEffect(() => {\n if (isVisible) {\n forceUpdate({});\n }\n }, [isVisible]);\n\n const getTooltipStyles = (): React.CSSProperties => {\n if (!triggerRef.current) {\n return { display: 'none' };\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n\n const baseStyles: React.CSSProperties = {\n position: 'fixed',\n display: 'flex',\n width: 'max-content',\n maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,\n minWidth: '32px',\n minHeight: '32px',\n padding: '8px 12px',\n alignItems: 'center',\n gap: '8px',\n borderRadius: '12px',\n backgroundColor: 'var(--malachite-tooltip-background, rgb(59, 59, 59))',\n color: 'var(--malachite-tooltip-foreground, rgb(255, 255, 255))',\n boxShadow: 'var(--malachite-tooltip-shadow, 0px 0px 10px 0px rgba(0, 0, 0, 0.20))',\n fontSize: '14px',\n lineHeight: '1.4',\n whiteSpace: 'normal',\n textAlign: 'left',\n pointerEvents: 'none',\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? 'visible' : 'hidden',\n transition:\n 'opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out',\n };\n\n // A trigger near the viewport edge would otherwise centre a wide tooltip half off\n // screen, where the panel or the window crops it. Clamping the CENTRE keeps the\n // `translateX(-50%)` placement honest: the box stays put, it just stops short.\n const centeredLeft = (): number => {\n const desired = rect.left + rect.width / 2;\n const width = tooltipRef.current?.getBoundingClientRect().width ?? 0;\n\n if (width === 0) {\n return desired;\n }\n\n const half = width / 2;\n const min = VIEWPORT_MARGIN + half;\n const max = window.innerWidth - VIEWPORT_MARGIN - half;\n\n // A tooltip wider than the viewport has no in-bounds centre; leave it centred\n // rather than pinning it to a nonsensical one.\n return min > max ? desired : Math.min(Math.max(desired, min), max);\n };\n\n switch (placement) {\n case 'top':\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'bottom':\n return {\n ...baseStyles,\n top: rect.bottom + 8,\n left: centeredLeft(),\n transform: `translateX(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'left':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.left - 8,\n transform: `translate(-100%, -50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'right':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.right + 8,\n transform: `translateY(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n default:\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n }\n };\n\n // Only reference the tooltip id once the portal can exist — a dangling\n // aria-describedby (text set, never shown) confuses assistive tech.\n const describedBy = hasText && hasShown && describesTrigger ? tooltipId : undefined;\n useInsertionEffect(() => {\n if (hasText && hasShown) {\n ensureOverlayStyles();\n }\n }, [hasText, hasShown]);\n const renderedChildren =\n wrapChildren || !React.isValidElement(children) ? (\n <span aria-describedby={describedBy} style={fill ? FILL_STYLE : undefined}>\n {children}\n </span>\n ) : (\n React.cloneElement(children as React.ReactElement, {\n 'aria-describedby':\n [(children as React.ReactElement).props['aria-describedby'], describedBy]\n .filter(Boolean)\n .join(' ') || undefined,\n })\n );\n\n const Trigger = inline ? 'span' : triggerAs;\n\n // Create the tooltip content without its own shadow root\n return (\n <>\n <Trigger\n ref={triggerRef}\n className={`relative ${inline ? 'inline-flex max-w-full align-middle' : 'flex'} items-center`}\n style={triggerStyle}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {renderedChildren}\n </Trigger>\n\n {hasText &&\n hasShown &&\n createPortal(\n <div\n ref={tooltipRef}\n id={tooltipId}\n role=\"tooltip\"\n // Nothing references it, and the sentence is already on screen and\n // described: left in the tree it is a second copy to read past.\n aria-hidden={describesTrigger ? undefined : true}\n {...overlayIdentity('tooltip')}\n style={getTooltipStyles()}\n >\n {/* min-w-0 + overflow-wrap let long values wrap within maxWidth. */}\n <span\n style={{\n minWidth: 0,\n overflowWrap: 'anywhere',\n }}\n >\n {typeof text === 'string' ? withBreakOpportunities(text) : text}\n </span>\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default Tooltip;\n"],"names":["WRAP_AFTER","withBreakOpportunities","value","chunk","i","jsxs","React","SHRINKABLE_STYLE","FILL_STYLE","VIEWPORT_MARGIN","Tooltip","text","children","delay","wrapChildren","triggerAs","inline","placement","isShrinkable","maxWidth","fill","shouldShow","suppressed","describesTrigger","showOnFocus","triggerStyle","isVisible","setIsVisible","useState","hasShown","setHasShown","timeoutRef","useRef","showFrameRef","cancelPendingShow","useCallback","scheduleVisible","tooltipRef","triggerRef","useTopLayer","tooltipId","useId","hasText","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","showOnFocusRef","useEffect","switchedOn","_a","wasSuppressed","setWasSuppressed","forceUpdate","handleUpdate","getTooltipStyles","rect","baseStyles","centeredLeft","desired","width","half","min","max","describedBy","useInsertionEffect","ensureOverlayStyles","renderedChildren","jsx","Fragment","createPortal","overlayIdentity"],"mappings":"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"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId, useInsertionEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { FOCUS_RING } from './focusRing';\nimport { ensureOverlayStyles, overlayIdentity } from './portalOverlay';\nimport { useTopLayer } from './topLayer';\n\n// Split after each delimiter so long values (URLs, dotted paths) wrap at \"/\" or \".\"\n// instead of mid-token. <wbr> is copy-safe (a zero-width space would corrupt a copied\n// URL); overflow-wrap still handles a single run too long to fit.\nconst WRAP_AFTER = /(?<=[/\\\\.\\-_?&#=:@])/;\nconst withBreakOpportunities = (value: string): React.ReactNode =>\n value.split(WRAP_AFTER).map((chunk, i) => (\n <React.Fragment key={i}>\n {chunk}\n <wbr />\n </React.Fragment>\n ));\n\ninterface TooltipProps {\n text: React.ReactNode | string;\n children: React.ReactNode;\n delay?: number;\n wrapChildren?: boolean;\n placement?: 'top' | 'bottom' | 'left' | 'right';\n isShrinkable?: boolean;\n fill?: boolean;\n /** Max width of tooltip. Default: 320px */\n maxWidth?: number | string;\n /** Called synchronously when the trigger is hovered/focused; return false to\n * suppress the tooltip for this interaction. Lets wrappers defer expensive\n * checks (e.g. truncation measurement) to interaction time instead of mount. */\n shouldShow?: () => boolean;\n suppressed?: boolean;\n triggerAs?: 'div' | 'span';\n inline?: boolean;\n /** Whether the tooltip acts as the trigger's accessible description. False where the\n * trigger already points at the same sentence on screen, so it is not announced twice. */\n describesTrigger?: boolean;\n /** False to open on hover only, e.g. where script moves focus onto the trigger. */\n showOnFocus?: boolean;\n /** Makes a trigger that cannot take focus a tab stop. Not for focusable children. */\n focusableTrigger?: boolean;\n}\n\nconst SHRINKABLE_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n};\n\nconst FILL_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\n/** Kept clear of the viewport edge so a clamped tooltip does not sit flush against it. */\nconst VIEWPORT_MARGIN = 8;\n\nconst Tooltip: React.FC<TooltipProps> = ({\n text,\n children,\n delay = 1,\n wrapChildren = false,\n triggerAs = 'div',\n inline = false,\n placement = 'top',\n isShrinkable = false,\n maxWidth = '320px',\n fill = false,\n shouldShow,\n suppressed = false,\n describesTrigger = true,\n showOnFocus = true,\n focusableTrigger = false,\n}) => {\n const triggerStyle =\n isShrinkable || fill\n ? { ...(isShrinkable ? SHRINKABLE_STYLE : {}), ...(fill ? FILL_STYLE : {}) }\n : undefined;\n\n const [isVisible, setIsVisible] = useState(false);\n // Portal mounts on first show, not on mount: an at-rest tooltip otherwise\n // costs a hidden document.body node plus a getBoundingClientRect per render —\n // multiplied by every row in a large table.\n // Mounted up front so a focusable trigger is described on first focus.\n const [hasShown, setHasShown] = useState(focusableTrigger);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showFrameRef = useRef<number | null>(null);\n\n const cancelPendingShow = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n showFrameRef.current = null;\n }\n }, []);\n\n const scheduleVisible = () => {\n // Two steps so the portal mounts hidden first and the fade-in transition\n // still runs on the very first show. The frame is tracked so leave/blur/\n // unmount can cancel a show that is already past its delay.\n setHasShown(true);\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n }\n showFrameRef.current = requestAnimationFrame(() => {\n showFrameRef.current = null;\n setIsVisible(true);\n });\n };\n const tooltipRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n // Tied to visibility, not mount: the node is latched into the DOM after its first show, and\n // re-entering on each show keeps a tooltip above the panel it is annotating.\n useTopLayer(tooltipRef, isVisible);\n\n const tooltipId = useId();\n\n const hasText = text !== null && text !== undefined && text !== '' && text !== false;\n\n const handleMouseEnter = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n if (!hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n\n timeoutRef.current = setTimeout(() => {\n scheduleVisible();\n }, delay * 1000);\n };\n\n const handleMouseLeave = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const handleFocus = () => {\n if (!showOnFocus || !hasText || suppressed || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n scheduleVisible();\n };\n\n const handleBlur = () => {\n cancelPendingShow();\n setIsVisible(false);\n };\n\n // Turning on while the trigger already holds focus fires no focus event to open on.\n const showOnFocusRef = useRef(showOnFocus);\n useEffect(() => {\n const switchedOn = showOnFocus && !showOnFocusRef.current;\n showOnFocusRef.current = showOnFocus;\n if (switchedOn && triggerRef.current?.matches(':focus-within')) {\n handleFocus();\n }\n });\n\n const [wasSuppressed, setWasSuppressed] = useState(suppressed);\n if (suppressed !== wasSuppressed) {\n setWasSuppressed(suppressed);\n if (suppressed) {\n setIsVisible(false);\n }\n }\n\n useEffect(() => {\n if (suppressed) {\n cancelPendingShow();\n }\n }, [suppressed, cancelPendingShow]);\n\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n // Only a VISIBLE tooltip needs to track scroll/resize; keeping global\n // listeners per mounted instance made every scroll event fan out across\n // every tooltip on the page.\n if (!isVisible) {\n return () => {\n cancelPendingShow();\n };\n }\n const handleUpdate = () => {\n forceUpdate({});\n };\n\n window.addEventListener('scroll', handleUpdate, true);\n window.addEventListener('resize', handleUpdate);\n\n return () => {\n cancelPendingShow();\n window.removeEventListener('scroll', handleUpdate, true);\n window.removeEventListener('resize', handleUpdate);\n };\n }, [isVisible, cancelPendingShow]);\n\n // The first render that mounts the tooltip has no measured width yet, so the clamp below\n // cannot run on it. One extra pass once it is in the DOM gives the clamp its measurement\n // — before the opacity transition finishes, so nothing is seen sliding into place.\n useEffect(() => {\n if (isVisible) {\n forceUpdate({});\n }\n }, [isVisible]);\n\n const getTooltipStyles = (): React.CSSProperties => {\n if (!triggerRef.current) {\n return { display: 'none' };\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n\n const baseStyles: React.CSSProperties = {\n position: 'fixed',\n display: 'flex',\n width: 'max-content',\n maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,\n minWidth: '32px',\n minHeight: '32px',\n padding: '8px 12px',\n alignItems: 'center',\n gap: '8px',\n borderRadius: '12px',\n backgroundColor: 'var(--malachite-tooltip-background, rgb(59, 59, 59))',\n color: 'var(--malachite-tooltip-foreground, rgb(255, 255, 255))',\n boxShadow: 'var(--malachite-tooltip-shadow, 0px 0px 10px 0px rgba(0, 0, 0, 0.20))',\n fontSize: '14px',\n lineHeight: '1.4',\n whiteSpace: 'normal',\n textAlign: 'left',\n pointerEvents: 'none',\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? 'visible' : 'hidden',\n transition:\n 'opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out',\n };\n\n // A trigger near the viewport edge would otherwise centre a wide tooltip half off\n // screen, where the panel or the window crops it. Clamping the CENTRE keeps the\n // `translateX(-50%)` placement honest: the box stays put, it just stops short.\n const centeredLeft = (): number => {\n const desired = rect.left + rect.width / 2;\n const width = tooltipRef.current?.getBoundingClientRect().width ?? 0;\n\n if (width === 0) {\n return desired;\n }\n\n const half = width / 2;\n const min = VIEWPORT_MARGIN + half;\n const max = window.innerWidth - VIEWPORT_MARGIN - half;\n\n // A tooltip wider than the viewport has no in-bounds centre; leave it centred\n // rather than pinning it to a nonsensical one.\n return min > max ? desired : Math.min(Math.max(desired, min), max);\n };\n\n switch (placement) {\n case 'top':\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'bottom':\n return {\n ...baseStyles,\n top: rect.bottom + 8,\n left: centeredLeft(),\n transform: `translateX(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'left':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.left - 8,\n transform: `translate(-100%, -50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'right':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.right + 8,\n transform: `translateY(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n default:\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n }\n };\n\n // Only reference the tooltip id once the portal can exist — a dangling\n // aria-describedby (text set, never shown) confuses assistive tech.\n const describedBy = hasText && hasShown && describesTrigger ? tooltipId : undefined;\n useInsertionEffect(() => {\n if (hasText && hasShown) {\n ensureOverlayStyles();\n }\n }, [hasText, hasShown]);\n const renderedChildren = focusableTrigger ? (\n children\n ) : wrapChildren || !React.isValidElement(children) ? (\n <span aria-describedby={describedBy} style={fill ? FILL_STYLE : undefined}>\n {children}\n </span>\n ) : (\n React.cloneElement(children as React.ReactElement, {\n 'aria-describedby':\n [(children as React.ReactElement).props['aria-describedby'], describedBy]\n .filter(Boolean)\n .join(' ') || undefined,\n })\n );\n\n const Trigger = inline ? 'span' : triggerAs;\n const isTabStop = focusableTrigger && hasText && !suppressed && showOnFocus;\n\n // Create the tooltip content without its own shadow root\n return (\n <>\n <Trigger\n ref={triggerRef}\n className={`relative ${inline ? 'inline-flex max-w-full align-middle' : 'flex'} items-center${isTabStop ? ` ${FOCUS_RING}` : ''}`}\n style={triggerStyle}\n tabIndex={isTabStop ? 0 : undefined}\n aria-describedby={focusableTrigger ? describedBy : undefined}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {renderedChildren}\n </Trigger>\n\n {hasText &&\n hasShown &&\n createPortal(\n <div\n ref={tooltipRef}\n id={tooltipId}\n role=\"tooltip\"\n // Nothing references it, and the sentence is already on screen and\n // described: left in the tree it is a second copy to read past.\n aria-hidden={describesTrigger ? undefined : true}\n {...overlayIdentity('tooltip')}\n style={getTooltipStyles()}\n >\n {/* min-w-0 + overflow-wrap let long values wrap within maxWidth. */}\n <span\n style={{\n minWidth: 0,\n overflowWrap: 'anywhere',\n }}\n >\n {typeof text === 'string' ? withBreakOpportunities(text) : text}\n </span>\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default Tooltip;\n"],"names":["WRAP_AFTER","withBreakOpportunities","value","chunk","i","jsxs","React","SHRINKABLE_STYLE","FILL_STYLE","VIEWPORT_MARGIN","Tooltip","text","children","delay","wrapChildren","triggerAs","inline","placement","isShrinkable","maxWidth","fill","shouldShow","suppressed","describesTrigger","showOnFocus","focusableTrigger","triggerStyle","isVisible","setIsVisible","useState","hasShown","setHasShown","timeoutRef","useRef","showFrameRef","cancelPendingShow","useCallback","scheduleVisible","tooltipRef","triggerRef","useTopLayer","tooltipId","useId","hasText","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","showOnFocusRef","useEffect","switchedOn","_a","wasSuppressed","setWasSuppressed","forceUpdate","handleUpdate","getTooltipStyles","rect","baseStyles","centeredLeft","desired","width","half","min","max","describedBy","useInsertionEffect","ensureOverlayStyles","renderedChildren","jsx","Trigger","isTabStop","Fragment","FOCUS_RING","createPortal","overlayIdentity"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { MENU_SPECS as r } from "./floatingMenuGeometry.js";
2
- import { injectStyleSheet as l } from "./injectStyleSheet.js";
2
+ import { injectStyleSheet as i } from "./injectStyleSheet.js";
3
3
  import { ensureOverlayStyles as s } from "./portalOverlay.js";
4
- import { SELECTED_ROW_BACKGROUND as i, SELECTED_ROW_FOREGROUND as d } from "./selectedRow.js";
4
+ import { SELECTED_ROW_BACKGROUND as l, SELECTED_ROW_FOREGROUND as d } from "./selectedRow.js";
5
5
  const y = {
6
6
  small: { icon: 16, iconBox: "text-[16px] [&_svg]:size-[16px]!" },
7
7
  xsmall: { icon: 11, iconBox: "text-[11px] [&_svg]:size-[11px]!" }
@@ -9,21 +9,29 @@ const y = {
9
9
  minWidth: 0,
10
10
  overflow: "hidden",
11
11
  textOverflow: "ellipsis"
12
+ }, w = {
13
+ position: "absolute",
14
+ width: 1,
15
+ height: 1,
16
+ margin: -1,
17
+ overflow: "hidden",
18
+ clipPath: "inset(50%)",
19
+ whiteSpace: "nowrap"
12
20
  }, m = {
13
21
  padding: "6px 10px",
14
22
  fontSize: "var(--malachite-font-size-small, 13px)",
15
23
  color: "var(--malachite-text-dimmed, rgb(161, 161, 161))",
16
24
  userSelect: "none"
17
- }, u = {
25
+ }, h = {
18
26
  ...m,
19
27
  color: "var(--malachite-text-secondary, rgb(123, 123, 123))",
20
28
  overflow: "hidden",
21
29
  textOverflow: "ellipsis",
22
30
  whiteSpace: "nowrap"
23
- }, g = { display: "inline-flex", flexShrink: 0 }, R = {
24
- ...g,
31
+ }, u = { display: "inline-flex", flexShrink: 0 }, R = {
32
+ ...u,
25
33
  color: "var(--malachite-text-dimmed, rgb(161, 161, 161))"
26
- }, n = "malachite-actionmenu-item-icon", a = "malachite-actionmenu-item", h = "data-malachite-actionmenu-tag", w = { display: "inline-flex", flexShrink: 0 }, I = { [h]: "" }, x = [
34
+ }, n = "malachite-actionmenu-item-icon", a = "malachite-actionmenu-item", g = "data-malachite-actionmenu-tag", I = { display: "inline-flex", flexShrink: 0 }, L = { [g]: "" }, x = [
27
35
  `.${a} { background: transparent; }`,
28
36
  `.${a}:not(:disabled):hover { background: var(--malachite-card-dimmed-background, rgb(247, 247, 247)); }`,
29
37
  `.${a}:focus-visible { outline: 2px solid var(--malachite-text-primary, rgb(10, 10, 10)); outline-offset: -2px; }`
@@ -31,18 +39,18 @@ const y = {
31
39
  `${t} { color: var(--malachite-text-primary, rgb(10, 10, 10)); }`,
32
40
  `${t}[data-tone="muted"] { color: var(--malachite-text-secondary, rgb(123, 123, 123)); }`,
33
41
  `${t} > .${n} { color: var(--malachite-text-dimmed, rgb(161, 161, 161)); }`,
34
- `${t}[aria-current] { color: ${d}; background: ${i}; }`,
42
+ `${t}[aria-current] { color: ${d}; background: ${l}; }`,
35
43
  `${c} { color: var(--malachite-text-destructive, rgb(237, 53, 54)); background: var(--malachite-error-background-glass, rgba(197, 63, 63, 0.08)); }`,
36
44
  `${c} > .${n} { color: inherit; }`
37
- ], v = () => l("malachite-actionmenu-danger-hover-styles", b), A = () => (s(), v(), l("malachite-actionmenu-item-styles", x)), S = {
45
+ ], v = () => i("malachite-actionmenu-danger-hover-styles", b), A = () => (s(), v(), i("malachite-actionmenu-item-styles", x)), S = {
38
46
  default: "var(--malachite-text-primary, rgb(10, 10, 10))",
39
47
  muted: "var(--malachite-text-secondary, rgb(123, 123, 123))"
40
- }, f = (e, o) => {
48
+ }, E = (e, o) => {
41
49
  if (e.danger === !0)
42
50
  return "var(--malachite-text-destructive, rgb(237, 53, 54))";
43
51
  if (e.danger !== "hover")
44
52
  return e.current ? d : S[o];
45
- }, $ = (e, o = "default") => e.type === "text" ? u : e.type === "divider" ? {
53
+ }, $ = (e, o = "default") => e.type === "text" ? h : e.type === "divider" ? {
46
54
  height: 1,
47
55
  background: "var(--malachite-card-border, rgb(232, 232, 232))",
48
56
  margin: "4px 0"
@@ -54,8 +62,8 @@ const y = {
54
62
  borderRadius: 8,
55
63
  fontSize: "var(--malachite-font-size-small, 13px)",
56
64
  fontWeight: 400,
57
- color: f(e, o),
58
- background: e.current && e.danger !== "hover" ? i : void 0,
65
+ color: E(e, o),
66
+ background: e.current && e.danger !== "hover" ? l : void 0,
59
67
  cursor: e.disabled ? "not-allowed" : "pointer",
60
68
  opacity: e.disabled ? 0.5 : 1,
61
69
  userSelect: "none",
@@ -66,7 +74,7 @@ const y = {
66
74
  textDecoration: "none",
67
75
  boxSizing: "border-box",
68
76
  width: "100%"
69
- }, L = (e) => ({
77
+ }, N = (e) => ({
70
78
  position: "fixed",
71
79
  top: (e == null ? void 0 : e.top) ?? 0,
72
80
  left: (e == null ? void 0 : e.left) ?? 0,
@@ -88,17 +96,18 @@ export {
88
96
  m as EMPTY_ITEM_STYLE,
89
97
  a as ITEM_CLASS,
90
98
  n as ITEM_ICON_CLASS,
91
- g as ITEM_ICON_LAYOUT,
99
+ u as ITEM_ICON_LAYOUT,
92
100
  R as ITEM_ICON_STYLE,
93
101
  O as LABEL_STYLE,
94
- h as TAG_HOST_ATTR,
95
- I as TAG_HOST_PROPS,
96
- w as TAG_HOST_STYLE,
97
- u as TEXT_ITEM_STYLE,
102
+ g as TAG_HOST_ATTR,
103
+ L as TAG_HOST_PROPS,
104
+ I as TAG_HOST_STYLE,
105
+ h as TEXT_ITEM_STYLE,
98
106
  y as TRIGGER_SIZES,
107
+ w as VISUALLY_HIDDEN_STYLE,
99
108
  A as ensureActionMenuStyles,
100
109
  v as ensureDangerOnHoverStyles,
101
110
  $ as itemStyle,
102
- L as menuStyle
111
+ N as menuStyle
103
112
  };
104
113
  //# sourceMappingURL=actionMenuStyles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"actionMenuStyles.js","sources":["../../src/components/actionMenuStyles.ts"],"sourcesContent":["import type React from 'react';\nimport type { ActionMenuItem } from './actionMenuTypes';\nimport { MENU_SPECS, type MenuGeometry } from './floatingMenuGeometry';\nimport { injectStyleSheet } from './injectStyleSheet';\nimport { ensureOverlayStyles } from './portalOverlay';\nimport { SELECTED_ROW_BACKGROUND, SELECTED_ROW_FOREGROUND } from './selectedRow';\n\nexport const TRIGGER_SIZES: Record<'small' | 'xsmall', { icon: number; iconBox: string }> = {\n small: { icon: 16, iconBox: 'text-[16px] [&_svg]:size-[16px]!' },\n xsmall: { icon: 11, iconBox: 'text-[11px] [&_svg]:size-[11px]!' },\n};\n\nexport const LABEL_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n};\n\nexport const EMPTY_ITEM_STYLE: React.CSSProperties = {\n padding: '6px 10px',\n fontSize: 'var(--malachite-font-size-small, 13px)',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n userSelect: 'none',\n};\n\nexport const TEXT_ITEM_STYLE: React.CSSProperties = {\n ...EMPTY_ITEM_STYLE,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n};\n\nexport const ITEM_ICON_LAYOUT: React.CSSProperties = { display: 'inline-flex', flexShrink: 0 };\n\nexport const ITEM_ICON_STYLE: React.CSSProperties = {\n ...ITEM_ICON_LAYOUT,\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n};\n\nexport const ITEM_ICON_CLASS = 'malachite-actionmenu-item-icon';\n\nexport const ITEM_CLASS = 'malachite-actionmenu-item';\n\nexport const TAG_HOST_ATTR = 'data-malachite-actionmenu-tag' as const;\n\nexport const TAG_HOST_STYLE: React.CSSProperties = { display: 'inline-flex', flexShrink: 0 };\n\nexport const TAG_HOST_PROPS = { [TAG_HOST_ATTR]: '' };\n\nconst ITEM_RULES = [\n `.${ITEM_CLASS} { background: transparent; }`,\n `.${ITEM_CLASS}:not(:disabled):hover { background: var(--malachite-card-dimmed-background, rgb(247, 247, 247)); }`,\n `.${ITEM_CLASS}:focus-visible { outline: 2px solid var(--malachite-text-primary, rgb(10, 10, 10)); outline-offset: -2px; }`,\n];\n\nconst DANGER_ON_HOVER = `.${ITEM_CLASS}[data-danger=\"hover\"]`;\nconst DANGER_ON_HOVER_ACTIVE = `${DANGER_ON_HOVER}:not(:disabled):is(:hover, :focus-visible)`;\n\nconst DANGER_ON_HOVER_RULES = [\n `${DANGER_ON_HOVER} { color: var(--malachite-text-primary, rgb(10, 10, 10)); }`,\n `${DANGER_ON_HOVER}[data-tone=\"muted\"] { color: var(--malachite-text-secondary, rgb(123, 123, 123)); }`,\n `${DANGER_ON_HOVER} > .${ITEM_ICON_CLASS} { color: var(--malachite-text-dimmed, rgb(161, 161, 161)); }`,\n `${DANGER_ON_HOVER}[aria-current] { color: ${SELECTED_ROW_FOREGROUND}; background: ${SELECTED_ROW_BACKGROUND}; }`,\n `${DANGER_ON_HOVER_ACTIVE} { color: var(--malachite-text-destructive, rgb(237, 53, 54)); background: var(--malachite-error-background-glass, rgba(197, 63, 63, 0.08)); }`,\n `${DANGER_ON_HOVER_ACTIVE} > .${ITEM_ICON_CLASS} { color: inherit; }`,\n];\n\nexport const ensureDangerOnHoverStyles = (): CSSStyleSheet | null =>\n injectStyleSheet('malachite-actionmenu-danger-hover-styles', DANGER_ON_HOVER_RULES);\n\nexport const ensureActionMenuStyles = (): CSSStyleSheet | null => {\n ensureOverlayStyles();\n ensureDangerOnHoverStyles();\n return injectStyleSheet('malachite-actionmenu-item-styles', ITEM_RULES);\n};\n\nexport type ActionMenuTone = 'default' | 'muted';\n\nconst ITEM_TEXT: Record<ActionMenuTone, string> = {\n default: 'var(--malachite-text-primary, rgb(10, 10, 10))',\n muted: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n};\n\ntype ActionItem = Exclude<ActionMenuItem, { type: 'text' } | { type: 'divider' }>;\n\nconst actionItemColor = (item: ActionItem, tone: ActionMenuTone): string | undefined => {\n if (item.danger === true) {\n return 'var(--malachite-text-destructive, rgb(237, 53, 54))';\n }\n if (item.danger === 'hover') {\n return undefined;\n }\n if (item.current) {\n return SELECTED_ROW_FOREGROUND;\n }\n return ITEM_TEXT[tone];\n};\n\nexport const itemStyle = (\n item: ActionMenuItem,\n tone: ActionMenuTone = 'default',\n): React.CSSProperties => {\n if (item.type === 'text') {\n return TEXT_ITEM_STYLE;\n }\n if (item.type === 'divider') {\n return {\n height: 1,\n background: 'var(--malachite-card-border, rgb(232, 232, 232))',\n margin: '4px 0',\n };\n }\n return {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 10px',\n borderRadius: 8,\n fontSize: 'var(--malachite-font-size-small, 13px)',\n fontWeight: 400,\n color: actionItemColor(item, tone),\n background: item.current && item.danger !== 'hover' ? SELECTED_ROW_BACKGROUND : undefined,\n cursor: item.disabled ? 'not-allowed' : 'pointer',\n opacity: item.disabled ? 0.5 : 1,\n userSelect: 'none',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n border: 'none',\n textAlign: 'left',\n textDecoration: 'none',\n boxSizing: 'border-box',\n width: '100%',\n };\n};\n\nexport const menuStyle = (position: MenuGeometry | null): React.CSSProperties => ({\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n width: position?.width,\n maxHeight: position?.maxHeight,\n overflowY: 'auto',\n background: MENU_SPECS.options.background,\n border: MENU_SPECS.options.border,\n borderRadius: MENU_SPECS.options.radius,\n boxShadow: MENU_SPECS.options.shadow,\n padding: MENU_SPECS.options.padding,\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n visibility: position ? 'visible' : 'hidden',\n opacity: position ? 1 : 0,\n});\n"],"names":["TRIGGER_SIZES","LABEL_STYLE","EMPTY_ITEM_STYLE","TEXT_ITEM_STYLE","ITEM_ICON_LAYOUT","ITEM_ICON_STYLE","ITEM_ICON_CLASS","ITEM_CLASS","TAG_HOST_ATTR","TAG_HOST_STYLE","TAG_HOST_PROPS","ITEM_RULES","DANGER_ON_HOVER","DANGER_ON_HOVER_ACTIVE","DANGER_ON_HOVER_RULES","SELECTED_ROW_FOREGROUND","SELECTED_ROW_BACKGROUND","ensureDangerOnHoverStyles","injectStyleSheet","ensureActionMenuStyles","ensureOverlayStyles","ITEM_TEXT","actionItemColor","item","tone","itemStyle","menuStyle","position","MENU_SPECS"],"mappings":"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"}
1
+ {"version":3,"file":"actionMenuStyles.js","sources":["../../src/components/actionMenuStyles.ts"],"sourcesContent":["import type React from 'react';\nimport type { ActionMenuItem } from './actionMenuTypes';\nimport { MENU_SPECS, type MenuGeometry } from './floatingMenuGeometry';\nimport { injectStyleSheet } from './injectStyleSheet';\nimport { ensureOverlayStyles } from './portalOverlay';\nimport { SELECTED_ROW_BACKGROUND, SELECTED_ROW_FOREGROUND } from './selectedRow';\n\nexport const TRIGGER_SIZES: Record<'small' | 'xsmall', { icon: number; iconBox: string }> = {\n small: { icon: 16, iconBox: 'text-[16px] [&_svg]:size-[16px]!' },\n xsmall: { icon: 11, iconBox: 'text-[11px] [&_svg]:size-[11px]!' },\n};\n\nexport const LABEL_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n};\n\n// Not `sr-only`: the menu portals outside the shadow root's stylesheet.\nexport const VISUALLY_HIDDEN_STYLE: React.CSSProperties = {\n position: 'absolute',\n width: 1,\n height: 1,\n margin: -1,\n overflow: 'hidden',\n clipPath: 'inset(50%)',\n whiteSpace: 'nowrap',\n};\n\nexport const EMPTY_ITEM_STYLE: React.CSSProperties = {\n padding: '6px 10px',\n fontSize: 'var(--malachite-font-size-small, 13px)',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n userSelect: 'none',\n};\n\nexport const TEXT_ITEM_STYLE: React.CSSProperties = {\n ...EMPTY_ITEM_STYLE,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n};\n\nexport const ITEM_ICON_LAYOUT: React.CSSProperties = { display: 'inline-flex', flexShrink: 0 };\n\nexport const ITEM_ICON_STYLE: React.CSSProperties = {\n ...ITEM_ICON_LAYOUT,\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n};\n\nexport const ITEM_ICON_CLASS = 'malachite-actionmenu-item-icon';\n\nexport const ITEM_CLASS = 'malachite-actionmenu-item';\n\nexport const TAG_HOST_ATTR = 'data-malachite-actionmenu-tag' as const;\n\nexport const TAG_HOST_STYLE: React.CSSProperties = { display: 'inline-flex', flexShrink: 0 };\n\nexport const TAG_HOST_PROPS = { [TAG_HOST_ATTR]: '' };\n\nconst ITEM_RULES = [\n `.${ITEM_CLASS} { background: transparent; }`,\n `.${ITEM_CLASS}:not(:disabled):hover { background: var(--malachite-card-dimmed-background, rgb(247, 247, 247)); }`,\n `.${ITEM_CLASS}:focus-visible { outline: 2px solid var(--malachite-text-primary, rgb(10, 10, 10)); outline-offset: -2px; }`,\n];\n\nconst DANGER_ON_HOVER = `.${ITEM_CLASS}[data-danger=\"hover\"]`;\nconst DANGER_ON_HOVER_ACTIVE = `${DANGER_ON_HOVER}:not(:disabled):is(:hover, :focus-visible)`;\n\nconst DANGER_ON_HOVER_RULES = [\n `${DANGER_ON_HOVER} { color: var(--malachite-text-primary, rgb(10, 10, 10)); }`,\n `${DANGER_ON_HOVER}[data-tone=\"muted\"] { color: var(--malachite-text-secondary, rgb(123, 123, 123)); }`,\n `${DANGER_ON_HOVER} > .${ITEM_ICON_CLASS} { color: var(--malachite-text-dimmed, rgb(161, 161, 161)); }`,\n `${DANGER_ON_HOVER}[aria-current] { color: ${SELECTED_ROW_FOREGROUND}; background: ${SELECTED_ROW_BACKGROUND}; }`,\n `${DANGER_ON_HOVER_ACTIVE} { color: var(--malachite-text-destructive, rgb(237, 53, 54)); background: var(--malachite-error-background-glass, rgba(197, 63, 63, 0.08)); }`,\n `${DANGER_ON_HOVER_ACTIVE} > .${ITEM_ICON_CLASS} { color: inherit; }`,\n];\n\nexport const ensureDangerOnHoverStyles = (): CSSStyleSheet | null =>\n injectStyleSheet('malachite-actionmenu-danger-hover-styles', DANGER_ON_HOVER_RULES);\n\nexport const ensureActionMenuStyles = (): CSSStyleSheet | null => {\n ensureOverlayStyles();\n ensureDangerOnHoverStyles();\n return injectStyleSheet('malachite-actionmenu-item-styles', ITEM_RULES);\n};\n\nexport type ActionMenuTone = 'default' | 'muted';\n\nconst ITEM_TEXT: Record<ActionMenuTone, string> = {\n default: 'var(--malachite-text-primary, rgb(10, 10, 10))',\n muted: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n};\n\ntype ActionItem = Exclude<ActionMenuItem, { type: 'text' } | { type: 'divider' }>;\n\nconst actionItemColor = (item: ActionItem, tone: ActionMenuTone): string | undefined => {\n if (item.danger === true) {\n return 'var(--malachite-text-destructive, rgb(237, 53, 54))';\n }\n if (item.danger === 'hover') {\n return undefined;\n }\n if (item.current) {\n return SELECTED_ROW_FOREGROUND;\n }\n return ITEM_TEXT[tone];\n};\n\nexport const itemStyle = (\n item: ActionMenuItem,\n tone: ActionMenuTone = 'default',\n): React.CSSProperties => {\n if (item.type === 'text') {\n return TEXT_ITEM_STYLE;\n }\n if (item.type === 'divider') {\n return {\n height: 1,\n background: 'var(--malachite-card-border, rgb(232, 232, 232))',\n margin: '4px 0',\n };\n }\n return {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 10px',\n borderRadius: 8,\n fontSize: 'var(--malachite-font-size-small, 13px)',\n fontWeight: 400,\n color: actionItemColor(item, tone),\n background: item.current && item.danger !== 'hover' ? SELECTED_ROW_BACKGROUND : undefined,\n cursor: item.disabled ? 'not-allowed' : 'pointer',\n opacity: item.disabled ? 0.5 : 1,\n userSelect: 'none',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n border: 'none',\n textAlign: 'left',\n textDecoration: 'none',\n boxSizing: 'border-box',\n width: '100%',\n };\n};\n\nexport const menuStyle = (position: MenuGeometry | null): React.CSSProperties => ({\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n width: position?.width,\n maxHeight: position?.maxHeight,\n overflowY: 'auto',\n background: MENU_SPECS.options.background,\n border: MENU_SPECS.options.border,\n borderRadius: MENU_SPECS.options.radius,\n boxShadow: MENU_SPECS.options.shadow,\n padding: MENU_SPECS.options.padding,\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n visibility: position ? 'visible' : 'hidden',\n opacity: position ? 1 : 0,\n});\n"],"names":["TRIGGER_SIZES","LABEL_STYLE","VISUALLY_HIDDEN_STYLE","EMPTY_ITEM_STYLE","TEXT_ITEM_STYLE","ITEM_ICON_LAYOUT","ITEM_ICON_STYLE","ITEM_ICON_CLASS","ITEM_CLASS","TAG_HOST_ATTR","TAG_HOST_STYLE","TAG_HOST_PROPS","ITEM_RULES","DANGER_ON_HOVER","DANGER_ON_HOVER_ACTIVE","DANGER_ON_HOVER_RULES","SELECTED_ROW_FOREGROUND","SELECTED_ROW_BACKGROUND","ensureDangerOnHoverStyles","injectStyleSheet","ensureActionMenuStyles","ensureOverlayStyles","ITEM_TEXT","actionItemColor","item","tone","itemStyle","menuStyle","position","MENU_SPECS"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ const h = (e, t) => e !== null ? "items" : t.trim().length > 0 ? "search" : "filters", a = (e, t) => {
2
+ const s = t.trim().toLowerCase();
3
+ return e.label.toLowerCase().includes(s) || e.value.toLowerCase().includes(s);
4
+ }, c = (e, t) => {
5
+ var s;
6
+ return new Set(((s = e.find((l) => l.filter === t)) == null ? void 0 : s.items) ?? []);
7
+ }, d = (e, t) => e.flatMap((s) => {
8
+ const l = c(t, s.value);
9
+ return s.items.map((o) => ({ item: o, filter: s, selected: l.has(o.value) }));
10
+ }), f = (e, t) => {
11
+ const s = e.filter((r) => a(r.item, t));
12
+ if (!s.some((r) => !r.item.disabled)) return null;
13
+ const l = e.every((r) => r.item.disabled || r.selected), o = t.trim().length > 0 && s.filter((r) => !r.item.disabled).every((r) => r.selected);
14
+ return l || o ? "deselect" : "select";
15
+ }, m = (e, t) => ({
16
+ toggle: f(e, t),
17
+ items: e.filter((s) => a(s.item, t))
18
+ }), g = (e, t, s) => e ? m(d([e], t), s) : { toggle: null, items: [] }, v = (e, t, s) => m(d(e, t), s), p = (e, t) => {
19
+ const s = new Set(t);
20
+ return e.length === s.size && e.every((l) => s.has(l));
21
+ }, i = (e, t) => {
22
+ const s = t.filter(
23
+ (n) => !p(n.items, [...c(e, n.filter)])
24
+ ), l = new Map(s.map((n) => [n.filter, n.items])), o = e.map((n) => ({
25
+ filter: n.filter,
26
+ items: l.get(n.filter) ?? n.items
27
+ })).filter((n) => n.items.length > 0), r = s.filter(
28
+ (n) => n.items.length > 0 && !e.some((u) => u.filter === n.filter)
29
+ );
30
+ return { next: [...o, ...r], changes: s };
31
+ }, w = (e, t, s) => {
32
+ const l = [...c(e, t)], o = l.includes(s) ? l.filter((r) => r !== s) : [...l, s];
33
+ return i(e, [{ filter: t, items: o }]);
34
+ }, S = (e, t, s) => i(
35
+ t,
36
+ e.map((l) => {
37
+ const o = c(t, l.value), r = l.items.filter(
38
+ (n) => !o.has(n.value) && !n.disabled && a(n, s)
39
+ ).map((n) => n.value);
40
+ return { filter: l.value, items: [...o, ...r] };
41
+ })
42
+ ), y = (e, t, s) => i(
43
+ t,
44
+ e.map((l) => {
45
+ const o = c(t, l.value), r = new Set(
46
+ l.items.filter((n) => !n.disabled && a(n, s)).map((n) => n.value)
47
+ );
48
+ return {
49
+ filter: l.value,
50
+ items: [...o].filter((n) => !r.has(n))
51
+ };
52
+ })
53
+ ), C = (e, t) => i(e, [{ filter: t, items: [] }]), F = (e) => i(
54
+ e,
55
+ e.map((t) => ({ filter: t.filter, items: [] }))
56
+ ), M = (e, t) => t.length === 0 ? e : t.length === 1 ? `${e}: ${t[0]}` : `${e}: (${t.join(", ")})`, $ = (e, t, s = null) => {
57
+ const l = new Set(e.map((r) => r.filter)), o = t.filter((r) => l.has(r) || r === s);
58
+ return [
59
+ ...o,
60
+ ...e.map((r) => r.filter).filter((r) => !o.includes(r))
61
+ ];
62
+ };
63
+ export {
64
+ M as chipText,
65
+ F as clearAll,
66
+ y as deselectAll,
67
+ g as filterRows,
68
+ a as matchesQuery,
69
+ $ as orderSelections,
70
+ C as removeFilter,
71
+ h as resolveMode,
72
+ v as searchRows,
73
+ S as selectAll,
74
+ w as toggleValue
75
+ };
76
+ //# sourceMappingURL=filterSearchModel.js.map