@particle-academy/react-fancy 4.11.0 → 4.12.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/README.md +1 -0
- package/dist/index.cjs +115 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +116 -2
- package/dist/index.js.map +1 -1
- package/dist/styles.css +62 -0
- package/dist/styles.css.map +1 -1
- package/docs/Marquee.md +96 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -130,6 +130,7 @@ npx vite build # Build demo app (verifies imports work)
|
|
|
130
130
|
| Card | Container with Header, Body, Footer compound slots | [docs](docs/Card.md) |
|
|
131
131
|
| Callout | Alert/info box with icon, color, and dismissible support | [docs](docs/Callout.md) |
|
|
132
132
|
| Timeline | Stacked, alternating, and horizontal timeline with data-driven or compound API | [docs](docs/Timeline.md) |
|
|
133
|
+
| Marquee | Auto-scrolling ticker strip with seamless wrap, px/s speed, fade edges, reduced-motion gate | [docs](docs/Marquee.md) |
|
|
133
134
|
|
|
134
135
|
### Overlay & Floating
|
|
135
136
|
|
package/dist/index.cjs
CHANGED
|
@@ -7703,6 +7703,120 @@ var TimeGrid = react.forwardRef(
|
|
|
7703
7703
|
}
|
|
7704
7704
|
);
|
|
7705
7705
|
TimeGrid.displayName = "TimeGrid";
|
|
7706
|
+
function toLength(value) {
|
|
7707
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
7708
|
+
}
|
|
7709
|
+
var Marquee = react.forwardRef(
|
|
7710
|
+
({
|
|
7711
|
+
children,
|
|
7712
|
+
items,
|
|
7713
|
+
speed = 40,
|
|
7714
|
+
duration,
|
|
7715
|
+
direction = "left",
|
|
7716
|
+
pauseOnHover = false,
|
|
7717
|
+
paused = false,
|
|
7718
|
+
gap = 40,
|
|
7719
|
+
fade = true,
|
|
7720
|
+
separator,
|
|
7721
|
+
angle = 0,
|
|
7722
|
+
decorative = true,
|
|
7723
|
+
className,
|
|
7724
|
+
style,
|
|
7725
|
+
...rest
|
|
7726
|
+
}, ref) => {
|
|
7727
|
+
const rootRef = react.useRef(null);
|
|
7728
|
+
const unitRef = react.useRef(null);
|
|
7729
|
+
react.useImperativeHandle(ref, () => rootRef.current);
|
|
7730
|
+
const [copies, setCopies] = react.useState(1);
|
|
7731
|
+
const [measuredDuration, setMeasuredDuration] = react.useState(null);
|
|
7732
|
+
react.useEffect(() => {
|
|
7733
|
+
const root = rootRef.current;
|
|
7734
|
+
const unit = unitRef.current;
|
|
7735
|
+
if (!root || !unit || typeof ResizeObserver === "undefined") return;
|
|
7736
|
+
const update = () => {
|
|
7737
|
+
const unitWidth = unit.getBoundingClientRect().width;
|
|
7738
|
+
const containerWidth = root.clientWidth;
|
|
7739
|
+
if (unitWidth <= 0) return;
|
|
7740
|
+
const nextCopies = Math.max(1, Math.ceil(containerWidth / unitWidth));
|
|
7741
|
+
setCopies(nextCopies);
|
|
7742
|
+
if (duration === void 0) {
|
|
7743
|
+
setMeasuredDuration(unitWidth * nextCopies / Math.max(speed, 1));
|
|
7744
|
+
}
|
|
7745
|
+
};
|
|
7746
|
+
update();
|
|
7747
|
+
const observer = new ResizeObserver(update);
|
|
7748
|
+
observer.observe(root);
|
|
7749
|
+
observer.observe(unit);
|
|
7750
|
+
return () => observer.disconnect();
|
|
7751
|
+
}, [duration, speed]);
|
|
7752
|
+
const loopSeconds = duration ?? measuredDuration ?? 40;
|
|
7753
|
+
const itemNodes = items ?? react.Children.toArray(children);
|
|
7754
|
+
const hasSeparator = separator !== void 0 && separator !== null;
|
|
7755
|
+
const renderUnit = (duplicate, unitElRef) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7756
|
+
"div",
|
|
7757
|
+
{
|
|
7758
|
+
ref: unitElRef,
|
|
7759
|
+
className: "fancy-marquee__unit",
|
|
7760
|
+
"aria-hidden": duplicate || void 0,
|
|
7761
|
+
children: itemNodes.map((node, i) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
7762
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "fancy-marquee__item", "data-react-fancy-marquee-item": "", "data-index": i, children: node }),
|
|
7763
|
+
hasSeparator && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7764
|
+
"div",
|
|
7765
|
+
{
|
|
7766
|
+
className: "fancy-marquee__separator",
|
|
7767
|
+
"data-react-fancy-marquee-separator": "",
|
|
7768
|
+
"aria-hidden": "true",
|
|
7769
|
+
children: separator
|
|
7770
|
+
}
|
|
7771
|
+
)
|
|
7772
|
+
] }, i))
|
|
7773
|
+
}
|
|
7774
|
+
);
|
|
7775
|
+
const renderGroup = (duplicate) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7776
|
+
"div",
|
|
7777
|
+
{
|
|
7778
|
+
className: "fancy-marquee__group",
|
|
7779
|
+
"data-react-fancy-marquee-group": "",
|
|
7780
|
+
"aria-hidden": duplicate || void 0,
|
|
7781
|
+
children: Array.from(
|
|
7782
|
+
{ length: copies },
|
|
7783
|
+
(_, c) => /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: renderUnit(duplicate || c > 0, !duplicate && c === 0 ? unitRef : void 0) }, c)
|
|
7784
|
+
)
|
|
7785
|
+
}
|
|
7786
|
+
);
|
|
7787
|
+
const cssVars = {
|
|
7788
|
+
"--fancy-marquee-duration": `${loopSeconds}s`,
|
|
7789
|
+
"--fancy-marquee-gap": toLength(gap),
|
|
7790
|
+
...fade !== false && {
|
|
7791
|
+
"--fancy-marquee-fade": fade === true ? "48px" : toLength(fade)
|
|
7792
|
+
}
|
|
7793
|
+
};
|
|
7794
|
+
const angleStyle = angle ? { transform: `rotate(${angle}deg)`, width: "102%", marginLeft: "-1%" } : {};
|
|
7795
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7796
|
+
"div",
|
|
7797
|
+
{
|
|
7798
|
+
ref: rootRef,
|
|
7799
|
+
"data-react-fancy-marquee": "",
|
|
7800
|
+
"data-direction": direction,
|
|
7801
|
+
"data-paused": paused ? "" : void 0,
|
|
7802
|
+
"aria-hidden": decorative || void 0,
|
|
7803
|
+
className: cn(
|
|
7804
|
+
"fancy-marquee",
|
|
7805
|
+
fade !== false && "fancy-marquee--fade",
|
|
7806
|
+
pauseOnHover && "fancy-marquee--pause-hover",
|
|
7807
|
+
className
|
|
7808
|
+
),
|
|
7809
|
+
style: { ...cssVars, ...angleStyle, ...style },
|
|
7810
|
+
...rest,
|
|
7811
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fancy-marquee__track", "data-react-fancy-marquee-track": "", children: [
|
|
7812
|
+
renderGroup(false),
|
|
7813
|
+
renderGroup(true)
|
|
7814
|
+
] })
|
|
7815
|
+
}
|
|
7816
|
+
);
|
|
7817
|
+
}
|
|
7818
|
+
);
|
|
7819
|
+
Marquee.displayName = "Marquee";
|
|
7706
7820
|
var Tooltip = react.forwardRef(
|
|
7707
7821
|
function Tooltip2({ children, content, placement = "top", delay = 200, offset = 8, className }, _ref) {
|
|
7708
7822
|
const [open, setOpen] = react.useState(false);
|
|
@@ -14891,6 +15005,7 @@ exports.Input = Input;
|
|
|
14891
15005
|
exports.InputTag = InputTag;
|
|
14892
15006
|
exports.Kanban = Kanban;
|
|
14893
15007
|
exports.MagicWand = MagicWand;
|
|
15008
|
+
exports.Marquee = Marquee;
|
|
14894
15009
|
exports.MediaViewer = MediaViewer;
|
|
14895
15010
|
exports.Menu = Menu2;
|
|
14896
15011
|
exports.MobileMenu = MobileMenu;
|