@smwb/ui-react 2.2.0 → 2.4.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/assets/styles/less/components/appBar/appBar.entry.css +1 -1
- package/dist/assets/styles/less/components/assetGrid/assetGrid.entry.css +1 -0
- package/dist/assets/styles/less/components/chipGroup/chipGroup.entry.css +1 -0
- package/dist/assets/styles/less/components/lazyImage/lazyImage.entry.css +1 -0
- package/dist/assets/styles/less/components/overflowMenu/overflowMenu.entry.css +1 -0
- package/dist/assets/styles/less/components/saveAssetDialog/saveAssetDialog.entry.css +1 -0
- package/dist/assets/styles/less/components/sheet/sheet.entry.css +1 -1
- package/dist/assets/styles/less/components/thumbCard/thumbCard.entry.css +1 -0
- package/dist/assets/styles/less/components/valueSlider/valueSlider.entry.css +1 -0
- package/dist/components/dataDisplay/assetGrid/assetGrid.d.ts +30 -0
- package/dist/components/dataDisplay/assetGrid/assetGrid.js +68 -0
- package/dist/components/dataDisplay/assetGrid/assetGrid.js.map +1 -0
- package/dist/components/dataDisplay/assetGrid/index.d.ts +2 -0
- package/dist/components/dataDisplay/chipGroup/chipGroup.d.ts +27 -0
- package/dist/components/dataDisplay/chipGroup/chipGroup.js +42 -0
- package/dist/components/dataDisplay/chipGroup/chipGroup.js.map +1 -0
- package/dist/components/dataDisplay/chipGroup/index.d.ts +2 -0
- package/dist/components/dataDisplay/lazyImage/index.d.ts +2 -0
- package/dist/components/dataDisplay/lazyImage/lazyImage.d.ts +22 -0
- package/dist/components/dataDisplay/lazyImage/lazyImage.js +52 -0
- package/dist/components/dataDisplay/lazyImage/lazyImage.js.map +1 -0
- package/dist/components/dataDisplay/thumbCard/index.d.ts +2 -0
- package/dist/components/dataDisplay/thumbCard/thumbCard.d.ts +29 -0
- package/dist/components/dataDisplay/thumbCard/thumbCard.js +82 -0
- package/dist/components/dataDisplay/thumbCard/thumbCard.js.map +1 -0
- package/dist/components/feedBack/saveAssetDialog/index.d.ts +2 -0
- package/dist/components/feedBack/saveAssetDialog/saveAssetDialog.d.ts +30 -0
- package/dist/components/feedBack/saveAssetDialog/saveAssetDialog.js +60 -0
- package/dist/components/feedBack/saveAssetDialog/saveAssetDialog.js.map +1 -0
- package/dist/components/inputs/valueSlider/index.d.ts +2 -0
- package/dist/components/inputs/valueSlider/valueSlider.d.ts +23 -0
- package/dist/components/inputs/valueSlider/valueSlider.js +55 -0
- package/dist/components/inputs/valueSlider/valueSlider.js.map +1 -0
- package/dist/components/navigation/menu/menuSubmenu.d.ts +1 -1
- package/dist/components/navigation/overflowMenu/index.d.ts +2 -0
- package/dist/components/navigation/overflowMenu/overflowMenu.d.ts +27 -0
- package/dist/components/navigation/overflowMenu/overflowMenu.js +54 -0
- package/dist/components/navigation/overflowMenu/overflowMenu.js.map +1 -0
- package/dist/headless/components/dataDisplay/assetGrid/assetGrid.js +67 -0
- package/dist/headless/components/dataDisplay/assetGrid/assetGrid.js.map +1 -0
- package/dist/headless/components/dataDisplay/chipGroup/chipGroup.js +41 -0
- package/dist/headless/components/dataDisplay/chipGroup/chipGroup.js.map +1 -0
- package/dist/headless/components/dataDisplay/lazyImage/lazyImage.js +51 -0
- package/dist/headless/components/dataDisplay/lazyImage/lazyImage.js.map +1 -0
- package/dist/headless/components/dataDisplay/thumbCard/thumbCard.js +81 -0
- package/dist/headless/components/dataDisplay/thumbCard/thumbCard.js.map +1 -0
- package/dist/headless/components/feedBack/saveAssetDialog/saveAssetDialog.js +59 -0
- package/dist/headless/components/feedBack/saveAssetDialog/saveAssetDialog.js.map +1 -0
- package/dist/headless/components/inputs/valueSlider/valueSlider.js +54 -0
- package/dist/headless/components/inputs/valueSlider/valueSlider.js.map +1 -0
- package/dist/headless/components/navigation/overflowMenu/overflowMenu.js +53 -0
- package/dist/headless/components/navigation/overflowMenu/overflowMenu.js.map +1 -0
- package/dist/headless/hooks/useHoverPopover.js +117 -0
- package/dist/headless/hooks/useHoverPopover.js.map +1 -0
- package/dist/headless/index.js +242 -226
- package/dist/headless/index.js.map +1 -1
- package/dist/hooks/useHoverPopover.d.ts +73 -0
- package/dist/hooks/useHoverPopover.js +117 -0
- package/dist/hooks/useHoverPopover.js.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.js +242 -226
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valueSlider.js","sources":["../../../../../src/components/inputs/valueSlider/valueSlider.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"clsx\";\nimport { Slider, type SliderProps, type SliderValue } from \"../slider\";\n\nexport interface ValueSliderProps extends SliderProps {\n /**\n * Read-only value readout beside the label. `true` shows the raw value; pass a\n * formatter for units/precision (e.g. `(v) => `${v}%``). Reflects `value`.\n */\n readout?: boolean | ((value: SliderValue | undefined) => string);\n /** Content at the end of the header row — a reset button, a favourite star, etc. */\n endAdornment?: React.ReactNode;\n /** Renders a built-in reset control in the header; called on click. */\n onReset?: () => void;\n /** Accessible label for the reset control. */\n resetLabel?: string;\n}\n\nfunction formatReadout(readout: ValueSliderProps[\"readout\"], value: SliderValue | undefined): string {\n if (typeof readout === \"function\") return readout(value);\n if (Array.isArray(value)) return `${value[0]} – ${value[1]}`;\n return value == null ? \"\" : String(value);\n}\n\n/**\n * `Slider` plus the value-readout + adornment header row every app rebuilds: a\n * read-only formatted value next to the label, an optional reset \"eraser\", and an\n * `endAdornment` slot. A drop-in preset — all `Slider` props pass through; the\n * label is rendered in the header instead of inside Slider.\n */\nexport function ValueSlider({\n readout,\n endAdornment,\n onReset,\n resetLabel,\n label,\n className,\n ...sliderProps\n}: ValueSliderProps): React.ReactElement {\n const hasReadout = readout !== undefined && readout !== false;\n const showHeader = label != null || hasReadout || endAdornment != null || onReset != null;\n\n return (\n <div className={cn(\"smwb-value-slider\", className)}>\n {showHeader ? (\n <div className=\"smwb-value-slider__header\">\n {label != null ? <span className=\"smwb-value-slider__label\">{label}</span> : null}\n <span className=\"smwb-value-slider__spacer\" />\n {hasReadout ? (\n <span className=\"smwb-value-slider__readout\">{formatReadout(readout, sliderProps.value)}</span>\n ) : null}\n {endAdornment}\n {onReset != null ? (\n <button\n type=\"button\"\n className=\"smwb-value-slider__reset\"\n aria-label={resetLabel ?? \"Reset\"}\n disabled={!!sliderProps.disabled}\n onClick={() => onReset()}\n >\n <svg\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M3 12a9 9 0 1 0 3-6.7M3 4v4h4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n ) : null}\n </div>\n ) : null}\n <Slider {...sliderProps} />\n </div>\n );\n}\n\nexport default ValueSlider;\n"],"names":["formatReadout","readout","value","ValueSlider","endAdornment","onReset","resetLabel","label","className","sliderProps","hasReadout","showHeader","cn","jsxs","jsx","Slider"],"mappings":";;;AAkBA,SAASA,EAAcC,GAAsCC,GAAwC;AACnG,SAAI,OAAOD,KAAY,aAAmBA,EAAQC,CAAK,IACnD,MAAM,QAAQA,CAAK,IAAU,GAAGA,EAAM,CAAC,CAAC,MAAMA,EAAM,CAAC,CAAC,KACnDA,KAAS,OAAO,KAAK,OAAOA,CAAK;AAC1C;AAQO,SAASC,EAAY;AAAA,EAC1B,SAAAF;AAAA,EACA,cAAAG;AAAA,EACA,SAAAC;AAAA,EACA,YAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,GAAyC;AACvC,QAAMC,IAAaT,MAAY,UAAaA,MAAY,IAClDU,IAAaJ,KAAS,QAAQG,KAAcN,KAAgB,QAAQC,KAAW;AAErF,2BACG,OAAA,EAAI,WAAWO,EAAG,qBAAqBJ,CAAS,GAC9C,UAAA;AAAA,IAAAG,IACC,gBAAAE,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,MAAAN,KAAS,OAAO,gBAAAO,EAAC,QAAA,EAAK,WAAU,4BAA4B,aAAM,IAAU;AAAA,MAC7E,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAAA,CAA4B;AAAA,MAC3CJ,IACC,gBAAAI,EAAC,QAAA,EAAK,WAAU,8BAA8B,YAAcb,GAASQ,EAAY,KAAK,EAAA,CAAE,IACtF;AAAA,MACHL;AAAA,MACAC,KAAW,OACV,gBAAAS;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,cAAYR,KAAA,OAAAA,IAAc;AAAA,UAC1B,UAAU,CAAC,CAACG,EAAY;AAAA,UACxB,SAAS,MAAMJ,EAAA;AAAA,UAEf,UAAA,gBAAAS;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,OAAM;AAAA,cACN,QAAO;AAAA,cACP,eAAY;AAAA,cACZ,MAAK;AAAA,cACL,QAAO;AAAA,cACP,aAAY;AAAA,cAEZ,4BAAC,QAAA,EAAK,GAAE,iCAAgC,eAAc,SAAQ,gBAAe,QAAA,CAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QACvF;AAAA,MAAA,IAEA;AAAA,IAAA,EAAA,CACN,IACE;AAAA,IACJ,gBAAAA,EAACC,GAAA,EAAQ,GAAGN,EAAA,CAAa;AAAA,EAAA,GAC3B;AAEJ;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs as f, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as h, useState as b } from "react";
|
|
3
|
+
import t from "clsx";
|
|
4
|
+
import { Button as v } from "../../inputs/button/button.js";
|
|
5
|
+
import { Menu as w } from "../menu/menu.js";
|
|
6
|
+
import { MenuItem as x } from "../menu/menuItem.js";
|
|
7
|
+
import { Icon as M } from "../../base/icon/icon.js";
|
|
8
|
+
function N({
|
|
9
|
+
items: u,
|
|
10
|
+
icon: p = "more_vert",
|
|
11
|
+
placement: r,
|
|
12
|
+
"aria-label": n,
|
|
13
|
+
disabled: d,
|
|
14
|
+
className: i
|
|
15
|
+
}) {
|
|
16
|
+
const s = h(null), [m, l] = b(!1), c = () => l(!1);
|
|
17
|
+
return /* @__PURE__ */ f("span", { className: t("smwb-overflow-menu", i), children: [
|
|
18
|
+
/* @__PURE__ */ e(
|
|
19
|
+
v,
|
|
20
|
+
{
|
|
21
|
+
ref: s,
|
|
22
|
+
variant: "text",
|
|
23
|
+
size: "small",
|
|
24
|
+
icon: p,
|
|
25
|
+
"aria-label": n != null ? n : "More actions",
|
|
26
|
+
"aria-haspopup": "menu",
|
|
27
|
+
disabled: !!d,
|
|
28
|
+
onClick: () => l((o) => !o)
|
|
29
|
+
}
|
|
30
|
+
),
|
|
31
|
+
/* @__PURE__ */ e(w, { isOpen: m, onClose: c, anchorElement: s.current, ...r ? { placement: r } : {}, children: u.map((o) => /* @__PURE__ */ f(
|
|
32
|
+
x,
|
|
33
|
+
{
|
|
34
|
+
className: t({ "smwb-overflow-menu__item--danger": o.danger }),
|
|
35
|
+
disabled: o.disabled,
|
|
36
|
+
onClick: () => {
|
|
37
|
+
var a;
|
|
38
|
+
o.disabled || ((a = o.onSelect) == null || a.call(o), c());
|
|
39
|
+
},
|
|
40
|
+
children: [
|
|
41
|
+
o.icon ? typeof o.icon == "string" ? /* @__PURE__ */ e(M, { name: o.icon }) : o.icon : null,
|
|
42
|
+
o.label
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
o.id
|
|
46
|
+
)) })
|
|
47
|
+
] });
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
N as OverflowMenu,
|
|
51
|
+
N as default
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=overflowMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overflowMenu.js","sources":["../../../../../src/components/navigation/overflowMenu/overflowMenu.tsx"],"sourcesContent":["import React, { useRef, useState } from \"react\";\nimport type { Placement } from \"@floating-ui/react\";\nimport cn from \"clsx\";\nimport { Button } from \"../../inputs/button\";\nimport { Icon } from \"../../base/icon\";\nimport { Menu, MenuItem } from \"../menu\";\n\nexport interface OverflowMenuItem {\n id: string;\n label: string;\n icon?: React.ReactNode | string;\n danger?: boolean;\n disabled?: boolean;\n onSelect?: () => void;\n}\n\nexport interface OverflowMenuProps {\n items: OverflowMenuItem[];\n /** Trigger icon name (default `more_vert`). */\n icon?: string;\n placement?: Placement;\n \"aria-label\"?: string;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * A one-shot kebab / overflow menu: a trigger icon button wired to a floating\n * `Menu` over an `items` array, with open/close state baked in. The card 3-dot\n * menu every app hand-builds (button + surface + open state) collapses to\n * passing an items list.\n */\nexport function OverflowMenu({\n items,\n icon = \"more_vert\",\n placement,\n \"aria-label\": ariaLabel,\n disabled,\n className,\n}: OverflowMenuProps): React.ReactElement {\n const anchorRef = useRef<HTMLButtonElement | HTMLAnchorElement | null>(null);\n const [open, setOpen] = useState(false);\n const close = (): void => setOpen(false);\n\n return (\n <span className={cn(\"smwb-overflow-menu\", className)}>\n <Button\n ref={anchorRef}\n variant=\"text\"\n size=\"small\"\n icon={icon}\n aria-label={ariaLabel ?? \"More actions\"}\n aria-haspopup=\"menu\"\n disabled={!!disabled}\n onClick={() => setOpen((value) => !value)}\n />\n <Menu isOpen={open} onClose={close} anchorElement={anchorRef.current} {...(placement ? { placement } : {})}>\n {items.map((item) => (\n <MenuItem\n key={item.id}\n className={cn({ \"smwb-overflow-menu__item--danger\": item.danger })}\n disabled={item.disabled}\n onClick={() => {\n if (item.disabled) return;\n item.onSelect?.();\n close();\n }}\n >\n {item.icon ? typeof item.icon === \"string\" ? <Icon name={item.icon} /> : item.icon : null}\n {item.label}\n </MenuItem>\n ))}\n </Menu>\n </span>\n );\n}\n\nexport default OverflowMenu;\n"],"names":["OverflowMenu","items","icon","placement","ariaLabel","disabled","className","anchorRef","useRef","open","setOpen","useState","close","cn","jsx","Button","value","Menu","item","jsxs","MenuItem","_a","Icon"],"mappings":";;;;;;;AAgCO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,WAAAC;AAAA,EACA,cAAcC;AAAA,EACd,UAAAC;AAAA,EACA,WAAAC;AACF,GAA0C;AACxC,QAAMC,IAAYC,EAAqD,IAAI,GACrE,CAACC,GAAMC,CAAO,IAAIC,EAAS,EAAK,GAChCC,IAAQ,MAAYF,EAAQ,EAAK;AAEvC,2BACG,QAAA,EAAK,WAAWG,EAAG,sBAAsBP,CAAS,GACjD,UAAA;AAAA,IAAA,gBAAAQ;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,KAAKR;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,MAAAL;AAAA,QACA,cAAYE,KAAA,OAAAA,IAAa;AAAA,QACzB,iBAAc;AAAA,QACd,UAAU,CAAC,CAACC;AAAA,QACZ,SAAS,MAAMK,EAAQ,CAACM,MAAU,CAACA,CAAK;AAAA,MAAA;AAAA,IAAA;AAAA,sBAEzCC,GAAA,EAAK,QAAQR,GAAM,SAASG,GAAO,eAAeL,EAAU,SAAU,GAAIJ,IAAY,EAAE,WAAAA,MAAc,CAAA,GACpG,UAAAF,EAAM,IAAI,CAACiB,MACV,gBAAAC;AAAA,MAACC;AAAA,MAAA;AAAA,QAEC,WAAWP,EAAG,EAAE,oCAAoCK,EAAK,QAAQ;AAAA,QACjE,UAAUA,EAAK;AAAA,QACf,SAAS,MAAM;;AACb,UAAIA,EAAK,cACTG,IAAAH,EAAK,aAAL,QAAAG,EAAA,KAAAH,IACAN,EAAA;AAAA,QACF;AAAA,QAEC,UAAA;AAAA,UAAAM,EAAK,OAAO,OAAOA,EAAK,QAAS,WAAW,gBAAAJ,EAACQ,GAAA,EAAK,MAAMJ,EAAK,KAAA,CAAM,IAAKA,EAAK,OAAO;AAAA,UACpFA,EAAK;AAAA,QAAA;AAAA,MAAA;AAAA,MAVDA,EAAK;AAAA,IAAA,CAYb,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { useState as k, useRef as m, useMemo as _, useCallback as e, useEffect as S } from "react";
|
|
2
|
+
import { offset as z, flip as B, shift as G, useFloating as V, autoUpdate as j } from "@floating-ui/react";
|
|
3
|
+
import { resolvePlacement as q } from "../utils/floating.js";
|
|
4
|
+
const J = "bottom-start", K = 4, Q = 8, W = ({ x: l, y: r }) => ({
|
|
5
|
+
x: l,
|
|
6
|
+
y: r,
|
|
7
|
+
top: r,
|
|
8
|
+
left: l,
|
|
9
|
+
right: l,
|
|
10
|
+
bottom: r,
|
|
11
|
+
width: 0,
|
|
12
|
+
height: 0
|
|
13
|
+
});
|
|
14
|
+
function H(l = {}) {
|
|
15
|
+
const {
|
|
16
|
+
placement: r = J,
|
|
17
|
+
offsetPx: T = K,
|
|
18
|
+
openDelay: M = 0,
|
|
19
|
+
closeDelay: R = 0,
|
|
20
|
+
middleware: a
|
|
21
|
+
} = l, [p, c] = k(!1), A = m({ x: 0, y: 0 }), F = m({ x: 0, y: 0 }), h = m(null), P = m(null), s = m(null), E = q(r), X = _(
|
|
22
|
+
() => [
|
|
23
|
+
z({ mainAxis: T, crossAxis: T }),
|
|
24
|
+
...E.autoMiddleware ? [E.autoMiddleware] : [B()],
|
|
25
|
+
G({ padding: Q }),
|
|
26
|
+
...a != null ? a : []
|
|
27
|
+
],
|
|
28
|
+
[T, E.autoMiddleware, a]
|
|
29
|
+
), { refs: g, floatingStyles: w, update: y } = V({
|
|
30
|
+
open: p,
|
|
31
|
+
placement: E.placement,
|
|
32
|
+
whileElementsMounted: j,
|
|
33
|
+
middleware: X
|
|
34
|
+
}), x = _(
|
|
35
|
+
() => ({ getBoundingClientRect: () => W(F.current) }),
|
|
36
|
+
[]
|
|
37
|
+
), o = e(() => {
|
|
38
|
+
P.current !== null && (clearTimeout(P.current), P.current = null), s.current !== null && (clearTimeout(s.current), s.current = null);
|
|
39
|
+
}, []);
|
|
40
|
+
S(() => () => o(), [o]), S(() => {
|
|
41
|
+
var t;
|
|
42
|
+
p && (g.setPositionReference((t = h.current) != null ? t : x), y());
|
|
43
|
+
}, [p, g, y, x]);
|
|
44
|
+
const f = e(() => {
|
|
45
|
+
h.current === null && (F.current = A.current);
|
|
46
|
+
}, []), b = e(() => {
|
|
47
|
+
o(), f(), c(!0);
|
|
48
|
+
}, [o, f]), v = e(() => {
|
|
49
|
+
if (o(), M <= 0) {
|
|
50
|
+
f(), c(!0);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
P.current = setTimeout(() => {
|
|
54
|
+
f(), c(!0);
|
|
55
|
+
}, M);
|
|
56
|
+
}, [o, f, M]), u = e(() => {
|
|
57
|
+
if (o(), R <= 0) {
|
|
58
|
+
c(!1);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
s.current = setTimeout(() => c(!1), R);
|
|
62
|
+
}, [o, R]), N = e(() => {
|
|
63
|
+
o(), c(!1);
|
|
64
|
+
}, [o]), O = e((t) => {
|
|
65
|
+
h.current = null, F.current = t;
|
|
66
|
+
}, []), U = e((t) => {
|
|
67
|
+
h.current = t;
|
|
68
|
+
}, []), D = e(
|
|
69
|
+
(t) => {
|
|
70
|
+
A.current = { x: t.clientX, y: t.clientY }, v();
|
|
71
|
+
},
|
|
72
|
+
[v]
|
|
73
|
+
), L = e((t) => {
|
|
74
|
+
A.current = { x: t.clientX, y: t.clientY };
|
|
75
|
+
}, []), I = e(
|
|
76
|
+
(t) => ({
|
|
77
|
+
onPointerEnter: (i) => {
|
|
78
|
+
var n;
|
|
79
|
+
(n = t == null ? void 0 : t.onPointerEnter) == null || n.call(t, i), D(i);
|
|
80
|
+
},
|
|
81
|
+
onPointerMove: (i) => {
|
|
82
|
+
var n;
|
|
83
|
+
(n = t == null ? void 0 : t.onPointerMove) == null || n.call(t, i), L(i);
|
|
84
|
+
},
|
|
85
|
+
onPointerLeave: (i) => {
|
|
86
|
+
var n;
|
|
87
|
+
(n = t == null ? void 0 : t.onPointerLeave) == null || n.call(t, i), u();
|
|
88
|
+
}
|
|
89
|
+
}),
|
|
90
|
+
[D, L, u]
|
|
91
|
+
), C = e(() => {
|
|
92
|
+
o(), c(!0);
|
|
93
|
+
}, [o]), Y = e(
|
|
94
|
+
(t) => ({
|
|
95
|
+
ref: g.setFloating,
|
|
96
|
+
style: { ...w, ...t == null ? void 0 : t.style },
|
|
97
|
+
onPointerEnter: C,
|
|
98
|
+
onPointerLeave: u
|
|
99
|
+
}),
|
|
100
|
+
[g, w, C, u]
|
|
101
|
+
);
|
|
102
|
+
return {
|
|
103
|
+
open: p,
|
|
104
|
+
getReferenceProps: I,
|
|
105
|
+
getFloatingProps: Y,
|
|
106
|
+
setAnchorEl: U,
|
|
107
|
+
setVirtualAnchor: O,
|
|
108
|
+
openNow: b,
|
|
109
|
+
scheduleOpen: v,
|
|
110
|
+
scheduleClose: u,
|
|
111
|
+
close: N
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
H as useHoverPopover
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=useHoverPopover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHoverPopover.js","sources":["../../../src/hooks/useHoverPopover.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties, PointerEvent as ReactPointerEvent } from \"react\";\nimport { autoUpdate, flip, offset, shift, useFloating } from \"@floating-ui/react\";\nimport type { Middleware, VirtualElement } from \"@floating-ui/react\";\nimport { resolvePlacement } from \"../utils/floating\";\nimport type { Placement } from \"../utils/floating\";\n\nexport interface UseHoverPopoverParams {\n /** Placement of the popover relative to its anchor. Default `\"bottom-start\"`. */\n placement?: Placement;\n /** Offset (px) applied on both axes between the anchor and the popover. Default `4`. */\n offsetPx?: number;\n /** Delay (ms) before opening after pointer enter. Default `0`. */\n openDelay?: number;\n /** Delay (ms) before closing after pointer leave. Default `0`. */\n closeDelay?: number;\n /** Extra floating-ui middleware appended after the smwb defaults. */\n middleware?: Middleware[];\n}\n\n/** A pointer position in viewport (client) coordinates. */\nexport interface HoverPopoverPoint {\n x: number;\n y: number;\n}\n\nexport interface HoverPopoverReferenceProps {\n onPointerEnter: (event: ReactPointerEvent) => void;\n onPointerMove: (event: ReactPointerEvent) => void;\n onPointerLeave: (event: ReactPointerEvent) => void;\n}\n\nexport interface HoverPopoverFloatingProps {\n ref: (node: HTMLElement | null) => void;\n style: CSSProperties;\n onPointerEnter: () => void;\n onPointerLeave: () => void;\n}\n\nexport interface UseHoverPopoverResult {\n /** Whether the popover is currently open. */\n open: boolean;\n /**\n * Pointer handlers for the trigger element(s). Spread on a single anchor, or\n * on EVERY row of a list/table to share one popover across many triggers. By\n * default the popover is anchored to the cursor position frozen when it opens.\n * Pass your own handlers to compose them (e.g. to mark which row is active).\n */\n getReferenceProps: (userHandlers?: Partial<HoverPopoverReferenceProps>) => HoverPopoverReferenceProps;\n /** Props for the single floating element; keeps it open while it is hovered. */\n getFloatingProps: (userProps?: { style?: CSSProperties }) => HoverPopoverFloatingProps;\n /** Anchor the popover to a real element instead of the cursor (`null` clears it). */\n setAnchorEl: (element: Element | null) => void;\n /** Anchor the popover to an explicit point, e.g. an external cursor source. */\n setVirtualAnchor: (point: HoverPopoverPoint) => void;\n /** Open immediately, ignoring `openDelay`. */\n openNow: () => void;\n /** Open after `openDelay`. */\n scheduleOpen: () => void;\n /** Close after `closeDelay`. */\n scheduleClose: () => void;\n /** Close immediately. */\n close: () => void;\n}\n\nconst DEFAULT_PLACEMENT: Placement = \"bottom-start\";\nconst DEFAULT_OFFSET_PX = 4;\nconst SHIFT_PADDING_PX = 8;\n\nconst rectFromPoint = ({ x, y }: HoverPopoverPoint) => ({\n x,\n y,\n top: y,\n left: x,\n right: x,\n bottom: y,\n width: 0,\n height: 0,\n});\n\n/**\n * Headless hover-popover positioning.\n *\n * Wraps floating-ui with the smwb placement / offset / flip / shift conventions\n * but imposes NO DOM structure: spread `getReferenceProps()` on any trigger\n * (including a `<tr>`, which the wrapper-based `<Tooltip>` cannot do) and\n * `getFloatingProps()` on a single floating element you render yourself.\n *\n * The default anchor is the cursor point frozen when the popover opens (a\n * floating-ui virtual element), so ONE instance can serve a whole table/list —\n * call `getReferenceProps()` on every row and render one shared popover instead\n * of mounting one floating engine per row. Use `setAnchorEl` to anchor to a\n * real element instead.\n */\nexport function useHoverPopover(params: UseHoverPopoverParams = {}): UseHoverPopoverResult {\n const {\n placement = DEFAULT_PLACEMENT,\n offsetPx = DEFAULT_OFFSET_PX,\n openDelay = 0,\n closeDelay = 0,\n middleware,\n } = params;\n\n const [open, setOpen] = useState(false);\n\n const cursorRef = useRef<HoverPopoverPoint>({ x: 0, y: 0 });\n const anchorRef = useRef<HoverPopoverPoint>({ x: 0, y: 0 });\n const anchorElRef = useRef<Element | null>(null);\n const openTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resolved = resolvePlacement(placement);\n\n const floatingMiddleware = useMemo<Middleware[]>(\n () => [\n offset({ mainAxis: offsetPx, crossAxis: offsetPx }),\n ...(resolved.autoMiddleware ? [resolved.autoMiddleware] : [flip()]),\n shift({ padding: SHIFT_PADDING_PX }),\n ...(middleware ?? []),\n ],\n [offsetPx, resolved.autoMiddleware, middleware]\n );\n\n const { refs, floatingStyles, update } = useFloating({\n open,\n placement: resolved.placement,\n whileElementsMounted: autoUpdate,\n middleware: floatingMiddleware,\n });\n\n const virtualReference = useMemo<VirtualElement>(\n () => ({ getBoundingClientRect: () => rectFromPoint(anchorRef.current) }),\n []\n );\n\n const clearTimers = useCallback(() => {\n if (openTimerRef.current !== null) {\n clearTimeout(openTimerRef.current);\n openTimerRef.current = null;\n }\n if (closeTimerRef.current !== null) {\n clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n }, []);\n\n useEffect(() => () => clearTimers(), [clearTimers]);\n\n // Apply the active anchor (element or frozen cursor) whenever the popover\n // opens; autoUpdate keeps it positioned while the floating element is mounted.\n useEffect(() => {\n if (!open) return;\n refs.setPositionReference(anchorElRef.current ?? virtualReference);\n void update();\n }, [open, refs, update, virtualReference]);\n\n const freezeAnchor = useCallback(() => {\n if (anchorElRef.current === null) anchorRef.current = cursorRef.current;\n }, []);\n\n const openNow = useCallback(() => {\n clearTimers();\n freezeAnchor();\n setOpen(true);\n }, [clearTimers, freezeAnchor]);\n\n const scheduleOpen = useCallback(() => {\n clearTimers();\n if (openDelay <= 0) {\n freezeAnchor();\n setOpen(true);\n return;\n }\n openTimerRef.current = setTimeout(() => {\n freezeAnchor();\n setOpen(true);\n }, openDelay);\n }, [clearTimers, freezeAnchor, openDelay]);\n\n const scheduleClose = useCallback(() => {\n clearTimers();\n if (closeDelay <= 0) {\n setOpen(false);\n return;\n }\n closeTimerRef.current = setTimeout(() => setOpen(false), closeDelay);\n }, [clearTimers, closeDelay]);\n\n const close = useCallback(() => {\n clearTimers();\n setOpen(false);\n }, [clearTimers]);\n\n const setVirtualAnchor = useCallback((point: HoverPopoverPoint) => {\n anchorElRef.current = null;\n anchorRef.current = point;\n }, []);\n\n const setAnchorEl = useCallback((element: Element | null) => {\n anchorElRef.current = element;\n }, []);\n\n const handleEnter = useCallback(\n (event: ReactPointerEvent) => {\n cursorRef.current = { x: event.clientX, y: event.clientY };\n scheduleOpen();\n },\n [scheduleOpen]\n );\n\n const handleMove = useCallback((event: ReactPointerEvent) => {\n cursorRef.current = { x: event.clientX, y: event.clientY };\n }, []);\n\n const getReferenceProps = useCallback<UseHoverPopoverResult[\"getReferenceProps\"]>(\n (userHandlers) => ({\n onPointerEnter: (event) => {\n userHandlers?.onPointerEnter?.(event);\n handleEnter(event);\n },\n onPointerMove: (event) => {\n userHandlers?.onPointerMove?.(event);\n handleMove(event);\n },\n onPointerLeave: (event) => {\n userHandlers?.onPointerLeave?.(event);\n scheduleClose();\n },\n }),\n [handleEnter, handleMove, scheduleClose]\n );\n\n const cancelClose = useCallback(() => {\n clearTimers();\n setOpen(true);\n }, [clearTimers]);\n\n const getFloatingProps = useCallback<UseHoverPopoverResult[\"getFloatingProps\"]>(\n (userProps) => ({\n ref: refs.setFloating,\n style: { ...floatingStyles, ...userProps?.style },\n onPointerEnter: cancelClose,\n onPointerLeave: scheduleClose,\n }),\n [refs, floatingStyles, cancelClose, scheduleClose]\n );\n\n return {\n open,\n getReferenceProps,\n getFloatingProps,\n setAnchorEl,\n setVirtualAnchor,\n openNow,\n scheduleOpen,\n scheduleClose,\n close,\n };\n}\n"],"names":["DEFAULT_PLACEMENT","DEFAULT_OFFSET_PX","SHIFT_PADDING_PX","rectFromPoint","x","y","useHoverPopover","params","placement","offsetPx","openDelay","closeDelay","middleware","open","setOpen","useState","cursorRef","useRef","anchorRef","anchorElRef","openTimerRef","closeTimerRef","resolved","resolvePlacement","floatingMiddleware","useMemo","offset","flip","shift","refs","floatingStyles","update","useFloating","autoUpdate","virtualReference","clearTimers","useCallback","useEffect","_a","freezeAnchor","openNow","scheduleOpen","scheduleClose","close","setVirtualAnchor","point","setAnchorEl","element","handleEnter","event","handleMove","getReferenceProps","userHandlers","cancelClose","getFloatingProps","userProps"],"mappings":"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"}
|