portosaurus 2.0.3 → 2.1.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/bin/portosaurus.mjs +14 -327
- package/package.json +16 -11
- package/src/cli/build.mjs +43 -0
- package/src/cli/dev.mjs +31 -0
- package/src/cli/init.mjs +135 -0
- package/src/cli/serve.mjs +30 -0
- package/src/core/buildDocuConfig.mjs +664 -0
- package/src/core/{themePlugin.mjs → plugins/themePlugin.mjs} +1 -1
- package/src/template/.github/workflows/deploy.yml +52 -0
- package/src/template/.nojekyll +0 -0
- package/src/template/README.md +58 -0
- package/src/template/blog/authors.yml +1 -1
- package/src/template/blog/welcome.md +1 -1
- package/src/template/config.js +40 -23
- package/src/template/package.json +20 -0
- package/src/template/static/img/svg/icon-blog.svg +2 -0
- package/src/template/static/img/svg/icon-note.svg +2 -0
- package/src/{components → theme/components}/AboutSection/index.js +22 -13
- package/src/{components → theme/components}/AboutSection/styles.module.css +59 -48
- package/src/{components → theme/components}/ContactSection/index.js +31 -24
- package/src/{components → theme/components}/ContactSection/styles.module.css +31 -26
- package/src/{components → theme/components}/ExperienceSection/index.js +12 -7
- package/src/{components → theme/components}/ExperienceSection/styles.module.css +23 -20
- package/src/{components → theme/components}/HeroSection/index.js +9 -11
- package/src/{components → theme/components}/HeroSection/styles.module.css +44 -32
- package/src/{components → theme/components}/NoteIndex/index.js +10 -3
- package/src/{components → theme/components}/Preview/components/PreviewHeader.js +14 -8
- package/src/{components → theme/components}/Preview/components/Triggers/Pv.js +32 -7
- package/src/{components → theme/components}/Preview/components/Triggers/SrcPv.js +1 -5
- package/src/theme/components/Preview/index.js +3 -0
- package/src/{components → theme/components}/ProjectsSection/index.js +279 -224
- package/src/{components → theme/components}/ProjectsSection/styles.module.css +21 -17
- package/src/{components → theme/components}/ScrollToTop/index.js +18 -21
- package/src/{components → theme/components}/ScrollToTop/styles.module.css +10 -9
- package/src/theme/components/SocialLinks/index.js +125 -0
- package/src/{components → theme/components}/SocialLinks/styles.module.css +9 -7
- package/src/{components → theme/components}/Tooltip/index.js +4 -1
- package/src/theme/config/iconMappings.js +465 -0
- package/src/theme/config/metaTags.js +239 -0
- package/src/theme/config/prism.js +179 -0
- package/src/theme/config/sidebar.js +17 -0
- package/src/{css → theme/css}/bootstrap.css +0 -1
- package/src/theme/css/catppuccin.css +618 -0
- package/src/{css → theme/css}/custom.css +3 -9
- package/src/{css → theme/css}/tasks.css +43 -37
- package/src/theme/{MDXComponents.js → overrides/MDXComponents.js} +3 -3
- package/src/theme/{Root.js → overrides/Root.js} +2 -4
- package/src/{pages → theme/pages}/index.js +23 -39
- package/src/theme/pages/notes.js +83 -0
- package/src/{pages → theme/pages}/tasks.js +115 -56
- package/src/{core/client-utils → theme/utils}/HashNavigation.js +60 -49
- package/src/{core/client-utils → theme/utils}/updateTitle.js +21 -25
- package/src/{core/build-utils → utils/build}/cssUtils.mjs +5 -3
- package/src/{core/build-utils → utils/build}/generateFavicon.mjs +44 -12
- package/src/{core/build-utils → utils/build}/generateRobotsTxt.mjs +4 -3
- package/src/{core/build-utils → utils/build}/iconExtractor.mjs +7 -3
- package/src/utils/build/imageDownloader.mjs +159 -0
- package/src/{core/build-utils → utils/build}/imageProcessor.mjs +5 -6
- package/src/utils/helpers.mjs +153 -0
- package/src/utils/logger.mjs +53 -0
- package/src/utils/packageManager.mjs +88 -0
- package/src/components/Preview/index.js +0 -3
- package/src/components/SocialLinks/index.js +0 -130
- package/src/config/iconMappings.js +0 -329
- package/src/config/metaTags.js +0 -240
- package/src/config/prism.js +0 -179
- package/src/config/sidebar.js +0 -20
- package/src/core/build-utils/imageDownloader.mjs +0 -98
- package/src/core/createDocuConf.mjs +0 -472
- package/src/core/defaults.mjs +0 -67
- package/src/core/logger.mjs +0 -17
- package/src/core/packageManager.mjs +0 -72
- package/src/css/catppuccin.css +0 -632
- package/src/pages/notes.js +0 -87
- /package/src/template/notes/{welcome.md → welcome.mdx} +0 -0
- /package/src/{components → theme/components}/NoteIndex/styles.module.css +0 -0
- /package/src/{components → theme/components}/Preview/components/FeedbackStates.js +0 -0
- /package/src/{components → theme/components}/Preview/components/FileTabs.js +0 -0
- /package/src/{components → theme/components}/Preview/components/Triggers/index.js +0 -0
- /package/src/{components → theme/components}/Preview/components/ViewerWindow.js +0 -0
- /package/src/{components → theme/components}/Preview/hooks/useDeepLinkHash.js +0 -0
- /package/src/{components → theme/components}/Preview/hooks/useDockLayout.js +0 -0
- /package/src/{components → theme/components}/Preview/hooks/useFileFetch.js +0 -0
- /package/src/{components → theme/components}/Preview/renderers/CodeRenderer.js +0 -0
- /package/src/{components → theme/components}/Preview/renderers/ImageRenderer.js +0 -0
- /package/src/{components → theme/components}/Preview/renderers/PdfRenderer.js +0 -0
- /package/src/{components → theme/components}/Preview/renderers/WebRenderer.js +0 -0
- /package/src/{components → theme/components}/Preview/state/index.js +0 -0
- /package/src/{components → theme/components}/Preview/styles.module.css +0 -0
- /package/src/{components → theme/components}/Preview/utils/index.js +0 -0
- /package/src/{components → theme/components}/Tooltip/styles.module.css +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
/* Animations */
|
|
3
2
|
@keyframes fadeIn {
|
|
4
3
|
from {
|
|
@@ -95,7 +94,10 @@
|
|
|
95
94
|
opacity: 0;
|
|
96
95
|
animation: fadeIn 0.5s ease-out forwards;
|
|
97
96
|
height: 100%;
|
|
98
|
-
transition:
|
|
97
|
+
transition:
|
|
98
|
+
transform 0.3s ease,
|
|
99
|
+
box-shadow 0.3s ease,
|
|
100
|
+
border-color 0.3s ease;
|
|
99
101
|
border: 1px solid var(--ifm-shadow-color);
|
|
100
102
|
width: 100%;
|
|
101
103
|
}
|
|
@@ -181,7 +183,7 @@
|
|
|
181
183
|
}
|
|
182
184
|
|
|
183
185
|
.projectStateLabel {
|
|
184
|
-
font-size: 0.65rem;
|
|
186
|
+
font-size: 0.65rem;
|
|
185
187
|
font-weight: 500;
|
|
186
188
|
padding: 1px 4px;
|
|
187
189
|
border-radius: var(--ifm-global-radius);
|
|
@@ -329,7 +331,9 @@
|
|
|
329
331
|
justify-content: center;
|
|
330
332
|
cursor: pointer;
|
|
331
333
|
z-index: 5;
|
|
332
|
-
transition:
|
|
334
|
+
transition:
|
|
335
|
+
opacity 0.2s ease,
|
|
336
|
+
background-color 0.2s ease;
|
|
333
337
|
padding: 0;
|
|
334
338
|
box-shadow: var(--ifm-global-shadow-md);
|
|
335
339
|
}
|
|
@@ -408,12 +412,12 @@
|
|
|
408
412
|
overflow-x: auto;
|
|
409
413
|
overflow-y: hidden;
|
|
410
414
|
-webkit-overflow-scrolling: touch;
|
|
411
|
-
scrollbar-width: none;
|
|
412
|
-
-ms-overflow-style: none;
|
|
415
|
+
scrollbar-width: none;
|
|
416
|
+
-ms-overflow-style: none;
|
|
413
417
|
display: flex;
|
|
414
418
|
justify-content: center;
|
|
415
419
|
padding: 0.8rem 0;
|
|
416
|
-
max-width: 60vw;
|
|
420
|
+
max-width: 60vw;
|
|
417
421
|
scroll-padding: 0 20px;
|
|
418
422
|
margin: 0 5px;
|
|
419
423
|
position: relative;
|
|
@@ -459,7 +463,7 @@
|
|
|
459
463
|
/* Center alignment for dots */
|
|
460
464
|
.centerDots {
|
|
461
465
|
display: flex !important;
|
|
462
|
-
justify-content: center !important;
|
|
466
|
+
justify-content: center !important;
|
|
463
467
|
text-align: center !important;
|
|
464
468
|
margin: 0 auto;
|
|
465
469
|
}
|
|
@@ -586,7 +590,7 @@
|
|
|
586
590
|
display: flex;
|
|
587
591
|
justify-content: center;
|
|
588
592
|
}
|
|
589
|
-
|
|
593
|
+
|
|
590
594
|
.mobileNavigationControls .centerDots {
|
|
591
595
|
margin: 0 auto;
|
|
592
596
|
}
|
|
@@ -598,7 +602,7 @@
|
|
|
598
602
|
width: 40px;
|
|
599
603
|
height: 40px;
|
|
600
604
|
flex-shrink: 0;
|
|
601
|
-
z-index: 10;
|
|
605
|
+
z-index: 10;
|
|
602
606
|
}
|
|
603
607
|
|
|
604
608
|
.mobileNavigationControls .carouselControl:hover {
|
|
@@ -628,25 +632,25 @@
|
|
|
628
632
|
}
|
|
629
633
|
|
|
630
634
|
.mobileNavigationControls .dotsScrollContainer {
|
|
631
|
-
justify-content: flex-start;
|
|
635
|
+
justify-content: flex-start;
|
|
632
636
|
padding-left: 10px;
|
|
633
|
-
min-height: 40px;
|
|
637
|
+
min-height: 40px;
|
|
634
638
|
align-items: center;
|
|
635
639
|
}
|
|
636
|
-
|
|
640
|
+
|
|
637
641
|
.mobileNavigationControls .centerDots {
|
|
638
642
|
justify-content: center !important;
|
|
639
643
|
padding-left: 0;
|
|
640
644
|
}
|
|
641
|
-
|
|
645
|
+
|
|
642
646
|
.mobileNavigationControls .navDot:first-child {
|
|
643
647
|
margin-left: 2px;
|
|
644
648
|
}
|
|
645
|
-
|
|
649
|
+
|
|
646
650
|
.mobileNavigationControls .activeDot {
|
|
647
651
|
transform: scale(1.6);
|
|
648
652
|
opacity: 1;
|
|
649
|
-
box-shadow: 0 0 0 2px rgba(var(--ifm-color-primary-rgb), 0.5);
|
|
653
|
+
box-shadow: 0 0 0 2px rgba(var(--ifm-color-primary-rgb), 0.5);
|
|
650
654
|
}
|
|
651
655
|
}
|
|
652
656
|
|
|
@@ -799,7 +803,7 @@
|
|
|
799
803
|
|
|
800
804
|
.mobileNavigationControls .activeDot {
|
|
801
805
|
box-shadow: 0 0 0 1.5px rgba(var(--ifm-color-primary-rgb), 0.4);
|
|
802
|
-
transform: scale(1.5);
|
|
806
|
+
transform: scale(1.5);
|
|
803
807
|
}
|
|
804
808
|
}
|
|
805
809
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useState, useEffect, useRef } from
|
|
2
|
-
import { IoIosArrowUp } from
|
|
3
|
-
import styles from
|
|
1
|
+
import { useState, useEffect, useRef } from "react";
|
|
2
|
+
import { IoIosArrowUp } from "react-icons/io";
|
|
3
|
+
import styles from "./styles.module.css";
|
|
4
4
|
|
|
5
5
|
export default function ScrollToTop({ hideDelay = 1500 }) {
|
|
6
6
|
const [isVisible, setIsVisible] = useState(false);
|
|
@@ -9,12 +9,11 @@ export default function ScrollToTop({ hideDelay = 1500 }) {
|
|
|
9
9
|
const lastScrollTopRef = useRef(0);
|
|
10
10
|
|
|
11
11
|
const startHideTimer = () => {
|
|
12
|
-
|
|
13
12
|
// Clear any existing timeout
|
|
14
13
|
if (timeoutRef.current) {
|
|
15
14
|
clearTimeout(timeoutRef.current);
|
|
16
15
|
}
|
|
17
|
-
|
|
16
|
+
|
|
18
17
|
// Only start timer if not hovering
|
|
19
18
|
if (!isHovering) {
|
|
20
19
|
timeoutRef.current = setTimeout(() => {
|
|
@@ -24,23 +23,21 @@ export default function ScrollToTop({ hideDelay = 1500 }) {
|
|
|
24
23
|
};
|
|
25
24
|
|
|
26
25
|
useEffect(() => {
|
|
27
|
-
|
|
28
26
|
const handleScroll = () => {
|
|
29
|
-
const scrollTop =
|
|
27
|
+
const scrollTop =
|
|
28
|
+
window.pageYOffset || document.documentElement.scrollTop;
|
|
30
29
|
const isScrollingUp = scrollTop < lastScrollTopRef.current;
|
|
31
|
-
|
|
30
|
+
|
|
32
31
|
// Save the current scroll position
|
|
33
32
|
lastScrollTopRef.current = scrollTop;
|
|
34
|
-
|
|
33
|
+
|
|
35
34
|
// Show button when scrolling up past threshold
|
|
36
35
|
if (isScrollingUp && scrollTop > 300) {
|
|
37
|
-
|
|
38
36
|
setIsVisible(true);
|
|
39
37
|
startHideTimer();
|
|
40
38
|
} else {
|
|
41
|
-
|
|
42
39
|
setIsVisible(false);
|
|
43
|
-
|
|
40
|
+
|
|
44
41
|
if (timeoutRef.current) {
|
|
45
42
|
clearTimeout(timeoutRef.current);
|
|
46
43
|
}
|
|
@@ -48,11 +45,11 @@ export default function ScrollToTop({ hideDelay = 1500 }) {
|
|
|
48
45
|
};
|
|
49
46
|
|
|
50
47
|
// Set up event listener
|
|
51
|
-
window.addEventListener(
|
|
52
|
-
|
|
48
|
+
window.addEventListener("scroll", handleScroll, { passive: true });
|
|
49
|
+
|
|
53
50
|
// Clean up
|
|
54
51
|
return () => {
|
|
55
|
-
window.removeEventListener(
|
|
52
|
+
window.removeEventListener("scroll", handleScroll);
|
|
56
53
|
if (timeoutRef.current) {
|
|
57
54
|
clearTimeout(timeoutRef.current);
|
|
58
55
|
}
|
|
@@ -60,7 +57,6 @@ export default function ScrollToTop({ hideDelay = 1500 }) {
|
|
|
60
57
|
}, [hideDelay, isHovering]);
|
|
61
58
|
|
|
62
59
|
const handleMouseEnter = () => {
|
|
63
|
-
|
|
64
60
|
setIsHovering(true);
|
|
65
61
|
|
|
66
62
|
if (timeoutRef.current) {
|
|
@@ -69,23 +65,24 @@ export default function ScrollToTop({ hideDelay = 1500 }) {
|
|
|
69
65
|
};
|
|
70
66
|
|
|
71
67
|
const handleMouseLeave = () => {
|
|
72
|
-
|
|
73
68
|
setIsHovering(false);
|
|
74
69
|
startHideTimer();
|
|
75
70
|
};
|
|
76
71
|
|
|
77
72
|
const scrollToTop = () => {
|
|
78
|
-
const prefersReducedMotion = window.matchMedia(
|
|
79
|
-
|
|
73
|
+
const prefersReducedMotion = window.matchMedia(
|
|
74
|
+
"(prefers-reduced-motion: reduce)",
|
|
75
|
+
).matches;
|
|
76
|
+
|
|
80
77
|
window.scrollTo({
|
|
81
78
|
top: 0,
|
|
82
|
-
behavior: prefersReducedMotion ?
|
|
79
|
+
behavior: prefersReducedMotion ? "auto" : "smooth",
|
|
83
80
|
});
|
|
84
81
|
};
|
|
85
82
|
|
|
86
83
|
return (
|
|
87
84
|
<button
|
|
88
|
-
className={`${styles.scrollToTop} ${isVisible ? styles.visible :
|
|
85
|
+
className={`${styles.scrollToTop} ${isVisible ? styles.visible : ""}`}
|
|
89
86
|
onClick={scrollToTop}
|
|
90
87
|
onMouseEnter={handleMouseEnter}
|
|
91
88
|
onMouseLeave={handleMouseLeave}
|
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
opacity: 0;
|
|
18
18
|
transform: translateY(20px) scale(0.9);
|
|
19
19
|
pointer-events: none;
|
|
20
|
-
transition:
|
|
20
|
+
transition:
|
|
21
|
+
opacity 0.3s ease,
|
|
22
|
+
transform 0.3s ease,
|
|
23
|
+
background-color 0.3s ease;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
.scrollToTop.visible {
|
|
@@ -46,14 +49,13 @@
|
|
|
46
49
|
|
|
47
50
|
/* Responsive adjustments */
|
|
48
51
|
@media (max-width: 768px) {
|
|
49
|
-
|
|
50
52
|
.scrollToTop {
|
|
51
53
|
width: 45px;
|
|
52
54
|
height: 45px;
|
|
53
55
|
bottom: 25px;
|
|
54
56
|
right: 25px;
|
|
55
57
|
}
|
|
56
|
-
|
|
58
|
+
|
|
57
59
|
.scrollToTop svg {
|
|
58
60
|
width: 24px;
|
|
59
61
|
height: 24px;
|
|
@@ -61,27 +63,26 @@
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
@media (max-width: 480px) {
|
|
64
|
-
|
|
65
66
|
.scrollToTop {
|
|
66
|
-
width: 40px;
|
|
67
|
+
width: 40px;
|
|
67
68
|
height: 40px;
|
|
68
69
|
bottom: 20px;
|
|
69
70
|
right: 50%;
|
|
70
71
|
transform: translateX(50%) translateY(20px) scale(0.9);
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
+
|
|
73
74
|
.scrollToTop.visible {
|
|
74
75
|
transform: translateX(50%) scale(1);
|
|
75
76
|
}
|
|
76
|
-
|
|
77
|
+
|
|
77
78
|
.scrollToTop:hover {
|
|
78
79
|
transform: translateX(50%) translateY(-3px) scale(1.05);
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
+
|
|
81
82
|
.scrollToTop:active {
|
|
82
83
|
transform: translateX(50%) translateY(-1px) scale(1.02);
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
+
|
|
85
86
|
.scrollToTop svg {
|
|
86
87
|
width: 22px;
|
|
87
88
|
height: 22px;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo, useCallback } from "react";
|
|
2
|
+
import styles from "./styles.module.css";
|
|
3
|
+
import { FaQuestionCircle } from "react-icons/fa";
|
|
4
|
+
|
|
5
|
+
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
|
6
|
+
import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
7
|
+
|
|
8
|
+
import Tooltip from "../Tooltip";
|
|
9
|
+
import { iconMap } from "../../config/iconMappings";
|
|
10
|
+
|
|
11
|
+
// Default icon & icon
|
|
12
|
+
const DEFAULT_ICON = FaQuestionCircle;
|
|
13
|
+
const DEFAULT_COLOR = "var(--ifm-color-primary)";
|
|
14
|
+
|
|
15
|
+
export default function SocialIcons({ showAll = false }) {
|
|
16
|
+
const { siteConfig } = useDocusaurusContext();
|
|
17
|
+
const { customFields } = siteConfig;
|
|
18
|
+
const isBrowser = useIsBrowser();
|
|
19
|
+
|
|
20
|
+
const [animationDelays, setAnimationDelays] = useState({});
|
|
21
|
+
|
|
22
|
+
const allSocialLinks = customFields.socialLinks.links || [];
|
|
23
|
+
|
|
24
|
+
// FIX: `to prevent unnecessary recalculations`
|
|
25
|
+
const socialLinks = useMemo(() => {
|
|
26
|
+
return showAll ? allSocialLinks : allSocialLinks.filter((link) => link.pin);
|
|
27
|
+
}, [allSocialLinks, showAll]);
|
|
28
|
+
|
|
29
|
+
// Calculate delays based on screen size
|
|
30
|
+
const calculateDelays = useCallback(() => {
|
|
31
|
+
if (!isBrowser) return {};
|
|
32
|
+
|
|
33
|
+
const isTablet = window.innerWidth <= 768;
|
|
34
|
+
const isMobile = window.innerWidth <= 480;
|
|
35
|
+
const delays = {};
|
|
36
|
+
|
|
37
|
+
const baseDelay = isMobile ? 0.7 : isTablet ? 0.9 : 1.3;
|
|
38
|
+
const incrementDelay = 0.1;
|
|
39
|
+
|
|
40
|
+
socialLinks.forEach((_, index) => {
|
|
41
|
+
delays[index] = `${baseDelay + index * incrementDelay}s`;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return delays;
|
|
45
|
+
}, [isBrowser, socialLinks]);
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (!isBrowser) return;
|
|
49
|
+
|
|
50
|
+
// Set initial delays
|
|
51
|
+
setAnimationDelays(calculateDelays());
|
|
52
|
+
|
|
53
|
+
const handleResize = () => {
|
|
54
|
+
setAnimationDelays(calculateDelays());
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
window.addEventListener("resize", handleResize);
|
|
58
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
59
|
+
}, [isBrowser, calculateDelays]);
|
|
60
|
+
|
|
61
|
+
// Get icon component and color
|
|
62
|
+
const getIconDetails = (iconName) => {
|
|
63
|
+
if (!iconName) {
|
|
64
|
+
return {
|
|
65
|
+
icon: DEFAULT_ICON,
|
|
66
|
+
color: DEFAULT_COLOR,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const formattedIconName = iconName.toLowerCase();
|
|
71
|
+
const iconDetails = iconMap[formattedIconName];
|
|
72
|
+
|
|
73
|
+
if (!iconDetails) {
|
|
74
|
+
return {
|
|
75
|
+
icon: DEFAULT_ICON,
|
|
76
|
+
color: DEFAULT_COLOR,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
icon: iconDetails.icon,
|
|
82
|
+
color: iconDetails.color || DEFAULT_COLOR,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
if (socialLinks.length === 0) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<div className={styles.socialIcons}>
|
|
92
|
+
{socialLinks.map((social, index) => {
|
|
93
|
+
const { icon: IconComponent, color: iconColor } = getIconDetails(
|
|
94
|
+
social.icon,
|
|
95
|
+
);
|
|
96
|
+
const href = social.url || "#";
|
|
97
|
+
const displayColor = social.color || iconColor;
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<Tooltip
|
|
101
|
+
key={index}
|
|
102
|
+
msg={social.desc || social.icon || "Link"}
|
|
103
|
+
position="top"
|
|
104
|
+
color={displayColor}
|
|
105
|
+
underline={false}
|
|
106
|
+
>
|
|
107
|
+
<a
|
|
108
|
+
href={href}
|
|
109
|
+
target="_blank"
|
|
110
|
+
rel="noopener noreferrer"
|
|
111
|
+
className={styles.socialLink}
|
|
112
|
+
style={{
|
|
113
|
+
"--hover-color": displayColor,
|
|
114
|
+
animationDelay: animationDelays[index] || "0s",
|
|
115
|
+
}}
|
|
116
|
+
aria-label={social.icon || "social link"}
|
|
117
|
+
>
|
|
118
|
+
<IconComponent size={24} />
|
|
119
|
+
</a>
|
|
120
|
+
</Tooltip>
|
|
121
|
+
);
|
|
122
|
+
})}
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
2
1
|
/* Animation */
|
|
3
2
|
@keyframes fadeIn {
|
|
4
|
-
from {
|
|
5
|
-
|
|
3
|
+
from {
|
|
4
|
+
opacity: 0;
|
|
5
|
+
}
|
|
6
|
+
to {
|
|
7
|
+
opacity: 1;
|
|
8
|
+
}
|
|
6
9
|
}
|
|
7
10
|
|
|
8
|
-
|
|
9
11
|
.socialIcons {
|
|
10
12
|
display: flex;
|
|
11
13
|
align-items: center;
|
|
@@ -18,7 +20,9 @@
|
|
|
18
20
|
align-items: center;
|
|
19
21
|
justify-content: center;
|
|
20
22
|
color: var(--ifm-color-primary);
|
|
21
|
-
transition:
|
|
23
|
+
transition:
|
|
24
|
+
color 0.3s,
|
|
25
|
+
transform 0.2s;
|
|
22
26
|
position: relative;
|
|
23
27
|
animation: fadeIn 0.3s ease-out forwards;
|
|
24
28
|
opacity: 0;
|
|
@@ -31,7 +35,6 @@
|
|
|
31
35
|
color: var(--hover-color, var(--ifm-color-primary-dark));
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
|
|
35
38
|
/* Responsive */
|
|
36
39
|
@media (max-width: 768px) {
|
|
37
40
|
.socialIcons {
|
|
@@ -42,7 +45,6 @@
|
|
|
42
45
|
.socialLink {
|
|
43
46
|
margin: 0 9px;
|
|
44
47
|
}
|
|
45
|
-
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
/* Accessibility */
|
|
@@ -14,7 +14,10 @@ export default function Tooltip({
|
|
|
14
14
|
const containerRef = useRef(null);
|
|
15
15
|
|
|
16
16
|
const tooltipStyle = color
|
|
17
|
-
? {
|
|
17
|
+
? {
|
|
18
|
+
"--tooltip-color": color,
|
|
19
|
+
"--tooltip-text-color": "var(--ifm-font-color-base-inverse)",
|
|
20
|
+
}
|
|
18
21
|
: {};
|
|
19
22
|
|
|
20
23
|
const show = useCallback(() => {
|