@q2devel/q2-storybook 1.0.124 → 1.0.125
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.
|
@@ -29,6 +29,8 @@ type BlogCardProps = {
|
|
|
29
29
|
getTagUrl?: (tag: string, index: number) => string;
|
|
30
30
|
tagLinkTarget?: "_blank" | "_self" | "_parent" | "_top";
|
|
31
31
|
tagHoverEffect?: boolean;
|
|
32
|
+
onTagsHeightChange?: (height: number) => void;
|
|
33
|
+
targetTagsHeight?: number;
|
|
32
34
|
};
|
|
33
|
-
declare const BlogCard: ({ post, variant, fallbackBackgroundColor, textHorizontal, textVertical, buttonText, showSeparator, bodyLimit, titleLimit, href, className, createdAt, createdText, showDateInline, tags, onTagClick, getTagUrl, tagLinkTarget, tagHoverEffect, }: BlogCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
declare const BlogCard: ({ post, variant, fallbackBackgroundColor, textHorizontal, textVertical, buttonText, showSeparator, bodyLimit, titleLimit, href, className, createdAt, createdText, showDateInline, tags, onTagClick, getTagUrl, tagLinkTarget, tagHoverEffect, onTagsHeightChange, targetTagsHeight, }: BlogCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
34
36
|
export default BlogCard;
|
|
@@ -2,13 +2,18 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import Heading from "../../Base/heading/Heading";
|
|
3
3
|
import Button from "../../Base/button/Button";
|
|
4
4
|
import clsx from "clsx";
|
|
5
|
+
import { useRef, useCallback, useEffect } from "react";
|
|
5
6
|
const stripHtmlTags = (html) => {
|
|
6
7
|
return html.replace(/<\/?[^>]+(>|$)/g, "");
|
|
7
8
|
};
|
|
8
9
|
const truncateText = (text, limit) => {
|
|
9
10
|
return text.length > limit ? text.slice(0, limit).trim() + "…" : text;
|
|
10
11
|
};
|
|
11
|
-
const BlogCard = ({ post, variant = "imageOverlay", fallbackBackgroundColor = "bg-gray-200", textHorizontal = "center", textVertical = "center", buttonText = "Více informací", showSeparator = true, bodyLimit = 150, titleLimit = 50, href = "/blog", className = {}, createdAt = "", createdText = "Vytvořeno", showDateInline = false, tags = [], onTagClick, getTagUrl, tagLinkTarget = "_self", tagHoverEffect = true, }) => {
|
|
12
|
+
const BlogCard = ({ post, variant = "imageOverlay", fallbackBackgroundColor = "bg-gray-200", textHorizontal = "center", textVertical = "center", buttonText = "Více informací", showSeparator = true, bodyLimit = 150, titleLimit = 50, href = "/blog", className = {}, createdAt = "", createdText = "Vytvořeno", showDateInline = false, tags = [], onTagClick, getTagUrl, tagLinkTarget = "_self", tagHoverEffect = true, onTagsHeightChange, targetTagsHeight, }) => {
|
|
13
|
+
// Refs for dynamic height management
|
|
14
|
+
const tagsRef = useRef(null);
|
|
15
|
+
const observerRef = useRef(null);
|
|
16
|
+
const reportedHeightRef = useRef(0);
|
|
12
17
|
const { article = "", image = "", heading = "", button = "", description = "", separator = "", } = className;
|
|
13
18
|
const hasImage = Boolean(post.field_image_url);
|
|
14
19
|
const finalHref = href;
|
|
@@ -29,6 +34,55 @@ const BlogCard = ({ post, variant = "imageOverlay", fallbackBackgroundColor = "b
|
|
|
29
34
|
center: "justify-center",
|
|
30
35
|
bottom: "justify-end",
|
|
31
36
|
};
|
|
37
|
+
// Measure and report natural height
|
|
38
|
+
const measureAndReportHeight = useCallback(() => {
|
|
39
|
+
if (!tagsRef.current || !onTagsHeightChange)
|
|
40
|
+
return;
|
|
41
|
+
const originalMinHeight = tagsRef.current.style.minHeight;
|
|
42
|
+
tagsRef.current.style.minHeight = "auto";
|
|
43
|
+
// Force reflow
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
45
|
+
tagsRef.current.offsetHeight;
|
|
46
|
+
const naturalHeight = tagsRef.current.getBoundingClientRect().height;
|
|
47
|
+
if (naturalHeight !== reportedHeightRef.current && naturalHeight > 0) {
|
|
48
|
+
reportedHeightRef.current = naturalHeight;
|
|
49
|
+
onTagsHeightChange(naturalHeight);
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.log(`BlogCard ${post.id}: Reporting natural height ${naturalHeight}px`);
|
|
52
|
+
}
|
|
53
|
+
tagsRef.current.style.minHeight = originalMinHeight;
|
|
54
|
+
}, [onTagsHeightChange, post.id]);
|
|
55
|
+
// ResizeObserver to watch content changes
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!tagsRef.current)
|
|
58
|
+
return;
|
|
59
|
+
if (observerRef.current) {
|
|
60
|
+
observerRef.current.disconnect();
|
|
61
|
+
}
|
|
62
|
+
observerRef.current = new ResizeObserver(() => {
|
|
63
|
+
setTimeout(measureAndReportHeight, 10);
|
|
64
|
+
});
|
|
65
|
+
observerRef.current.observe(tagsRef.current);
|
|
66
|
+
// Initial measure
|
|
67
|
+
setTimeout(measureAndReportHeight, 0);
|
|
68
|
+
return () => {
|
|
69
|
+
if (observerRef.current) {
|
|
70
|
+
observerRef.current.disconnect();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}, [tags, measureAndReportHeight]);
|
|
74
|
+
// Apply target height when it changes
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (tagsRef.current && targetTagsHeight && targetTagsHeight > 0) {
|
|
77
|
+
tagsRef.current.style.minHeight = `${targetTagsHeight}px`;
|
|
78
|
+
// eslint-disable-next-line no-console
|
|
79
|
+
console.log(`BlogCard ${post.id}: Applied target height ${targetTagsHeight}px`);
|
|
80
|
+
}
|
|
81
|
+
}, [targetTagsHeight, post.id]);
|
|
82
|
+
// Re-measure when tags content changes
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
setTimeout(measureAndReportHeight, 0);
|
|
85
|
+
}, [tags, measureAndReportHeight]);
|
|
32
86
|
if (variant === "imageTop") {
|
|
33
87
|
return (_jsxs("article", { className: clsx("bg-white shadow-sm rounded overflow-hidden", article), children: [hasImage ? (_jsx("img", { alt: post.title, src: post.field_image_url, className: clsx("w-full h-48 object-cover", image) })) : (_jsxs("div", { className: clsx("w-full h-48 flex items-center justify-center", fallbackBackgroundColor), children: [_jsx("span", { className: "text-gray-600 text-center px-4 text-sm font-medium", children: limitedTitle }), _jsx("span", { className: "text-gray-600 text-center px-4 text-xs font-light", children: createdAt })] })), _jsxs("div", { className: "p-4", children: [showDateInline && createdAt ? (_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx(Heading, { level: 3, className: clsx("text-black font-semibold", heading), children: limitedTitle }), _jsx("span", { className: "text-black font-normal text-lg", children: createdAt })] })) : (_jsx(Heading, { level: 3, className: clsx("text-black font-semibold mb-2", heading), children: limitedTitle })), createdAt && !showDateInline && (_jsxs("p", { className: "text-gray-600 text-sm font-normal mb-2", children: [createdText, ": ", createdAt] })), tags && tags.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1 mb-3", children: tags.map((tagItem, index) => {
|
|
34
88
|
// Handle both string tags and tag objects
|