@portosaur/theme 0.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.
Files changed (76) hide show
  1. package/README.md +13 -0
  2. package/assets/img/icon-old.png +0 -0
  3. package/assets/img/icon.png +0 -0
  4. package/assets/img/project-blank.png +0 -0
  5. package/assets/img/social-card.jpeg +0 -0
  6. package/assets/img/svg/icon-blog.svg +2 -0
  7. package/assets/img/svg/icon-close.svg +3 -0
  8. package/assets/img/svg/icon-dock.svg +4 -0
  9. package/assets/img/svg/icon-link.svg +5 -0
  10. package/assets/img/svg/icon-note.svg +2 -0
  11. package/assets/img/svg/icon-popup.svg +1 -0
  12. package/assets/img/svg/icon-save.svg +5 -0
  13. package/assets/img/svg/icon.svg +240 -0
  14. package/assets/img/svg/project-blank.svg +140 -0
  15. package/assets/sample-resume.pdf +0 -0
  16. package/package.json +41 -0
  17. package/plugins/README.md +8 -0
  18. package/src/index.d.ts +11 -0
  19. package/src/index.mjs +14 -0
  20. package/src/plugins/theme.mjs +13 -0
  21. package/theme/DocCategoryGeneratedIndexPage/index.jsx +15 -0
  22. package/theme/MDXComponents.jsx +19 -0
  23. package/theme/README.md +9 -0
  24. package/theme/Root.jsx +11 -0
  25. package/theme/components/AboutSection/index.jsx +264 -0
  26. package/theme/components/AboutSection/styles.module.css +309 -0
  27. package/theme/components/ContactSection/index.jsx +188 -0
  28. package/theme/components/ContactSection/styles.module.css +343 -0
  29. package/theme/components/ExperienceSection/index.jsx +119 -0
  30. package/theme/components/ExperienceSection/styles.module.css +183 -0
  31. package/theme/components/HeroSection/index.jsx +198 -0
  32. package/theme/components/HeroSection/styles.module.css +484 -0
  33. package/theme/components/NavArrow/index.jsx +124 -0
  34. package/theme/components/NavArrow/styles.module.css +107 -0
  35. package/theme/components/NoteIndex/index.jsx +182 -0
  36. package/theme/components/NoteIndex/styles.module.css +167 -0
  37. package/theme/components/Preview/components/FeedbackStates.jsx +200 -0
  38. package/theme/components/Preview/components/FileTabs.jsx +41 -0
  39. package/theme/components/Preview/components/PreviewContent.jsx +104 -0
  40. package/theme/components/Preview/components/PreviewHeader.jsx +411 -0
  41. package/theme/components/Preview/components/Triggers/Pv.jsx +253 -0
  42. package/theme/components/Preview/components/Triggers/SrcPv.jsx +55 -0
  43. package/theme/components/Preview/components/Triggers/index.jsx +2 -0
  44. package/theme/components/Preview/components/ViewerWindow.jsx +489 -0
  45. package/theme/components/Preview/hooks/useAdaptiveSizing.jsx +90 -0
  46. package/theme/components/Preview/hooks/useDeepLinkHash.jsx +24 -0
  47. package/theme/components/Preview/hooks/useDockLayout.jsx +86 -0
  48. package/theme/components/Preview/hooks/useFileFetch.jsx +38 -0
  49. package/theme/components/Preview/hooks/useTouchZoom.jsx +98 -0
  50. package/theme/components/Preview/index.jsx +3 -0
  51. package/theme/components/Preview/renderers/CodeRenderer.jsx +124 -0
  52. package/theme/components/Preview/renderers/ImageRenderer.jsx +74 -0
  53. package/theme/components/Preview/renderers/PdfRenderer.jsx +93 -0
  54. package/theme/components/Preview/renderers/WebRenderer.jsx +59 -0
  55. package/theme/components/Preview/state/index.jsx +177 -0
  56. package/theme/components/Preview/styles.module.css +776 -0
  57. package/theme/components/Preview/utils/index.jsx +62 -0
  58. package/theme/components/ProjectsSection/index.jsx +790 -0
  59. package/theme/components/ProjectsSection/styles.module.css +900 -0
  60. package/theme/components/SocialLinks/index.jsx +115 -0
  61. package/theme/components/SocialLinks/styles.module.css +57 -0
  62. package/theme/components/Tooltip/index.jsx +104 -0
  63. package/theme/components/Tooltip/styles.module.css +168 -0
  64. package/theme/config/iconMappings.jsx +427 -0
  65. package/theme/config/prism.jsx +72 -0
  66. package/theme/config/sidebar.jsx +11 -0
  67. package/theme/css/bootstrap.css +5 -0
  68. package/theme/css/catppuccin.css +618 -0
  69. package/theme/css/custom.css +253 -0
  70. package/theme/css/tasks.css +874 -0
  71. package/theme/hooks/useScrollReveal.jsx +20 -0
  72. package/theme/pages/index.jsx +104 -0
  73. package/theme/pages/notes.jsx +131 -0
  74. package/theme/pages/tasks.jsx +989 -0
  75. package/theme/utils/HashNavigation.jsx +185 -0
  76. package/theme/utils/updateTitle.jsx +65 -0
@@ -0,0 +1,185 @@
1
+ import { useEffect, useRef } from "react";
2
+ export default function HashNavigation({
3
+ elementPrefix = "card-",
4
+ elementSelector = ".content-card",
5
+ containerSelector = ".container",
6
+ effectDuration = 6000,
7
+ scrollDelay = 300,
8
+ scrollOptions = { behavior: "smooth", block: "center" },
9
+ enabled = true,
10
+ styles = {},
11
+ }) {
12
+ const styleId = "hash-navigation-styles";
13
+ const highlightClass = "hash-nav-highlight";
14
+ const blurClass = "hash-nav-blur";
15
+ const containerActiveClass = "hash-nav-active";
16
+ const {
17
+ overlayColor = "rgba(var(--ifm-color-emphasis-200-rgb), 0.5)",
18
+ highlightShadow = "0 0 30px 10px var(--ifm-color-primary)",
19
+ highlightScale = "1.05",
20
+ blurAmount = "4px",
21
+ blurOpacity = "0.3",
22
+ } = styles;
23
+ const stylesInjected = useRef(false);
24
+ useEffect(() => {
25
+ if (document.getElementById(styleId) || stylesInjected.current) {
26
+ return;
27
+ }
28
+ const styleElement = document.createElement("style");
29
+ styleElement.id = styleId;
30
+ styleElement.innerHTML = `
31
+
32
+ ${containerSelector}.${containerActiveClass} {
33
+ position: relative;
34
+ }
35
+
36
+ ${containerSelector}.${containerActiveClass}::after {
37
+ content: '';
38
+ position: fixed;
39
+ top: 0;
40
+ left: 0;
41
+ width: 100%;
42
+ height: 100%;
43
+ background: ${overlayColor};
44
+ z-index: 10;
45
+ pointer-events: none;
46
+ }
47
+
48
+ .${highlightClass} {
49
+ position: relative;
50
+ z-index: 20;
51
+ transform: scale(${highlightScale});
52
+ box-shadow: ${highlightShadow};
53
+ transition: all 0.3s ease;
54
+ }
55
+
56
+ .${blurClass} {
57
+ filter: blur(${blurAmount}) grayscale(70%) brightness(0.8);
58
+ opacity: ${blurOpacity};
59
+ transition: all 0.3s ease;
60
+ background-color: rgba(var(--ifm-color-emphasis-200-rgb), 0.15);
61
+ pointer-events: none;
62
+ }
63
+
64
+ /* Clickable overlay for dismissing effects */
65
+ .hash-nav-overlay {
66
+ position: fixed;
67
+ top: 0;
68
+ left: 0;
69
+ width: 100%;
70
+ height: 100%;
71
+ z-index: 15;
72
+ cursor: pointer;
73
+ }
74
+
75
+ /* Reduced motion support */
76
+ @media (prefers-reduced-motion: reduce) {
77
+ .${highlightClass},
78
+ .${blurClass} {
79
+ transition: none !important;
80
+ }
81
+
82
+ .${highlightClass} {
83
+ transform: none !important;
84
+ }
85
+
86
+ .${blurClass} {
87
+ filter: opacity(${blurOpacity});
88
+ background-color: rgba(var(--ifm-color-emphasis-200-rgb), 0.15);
89
+ }
90
+ }
91
+ `;
92
+ document.head.appendChild(styleElement);
93
+ stylesInjected.current = true;
94
+ return () => {
95
+ const existingStyle = document.getElementById(styleId);
96
+ if (existingStyle) {
97
+ document.head.removeChild(existingStyle);
98
+ }
99
+ stylesInjected.current = false;
100
+ };
101
+ }, [
102
+ containerSelector,
103
+ overlayColor,
104
+ highlightShadow,
105
+ highlightScale,
106
+ blurAmount,
107
+ blurOpacity,
108
+ ]);
109
+ useEffect(() => {
110
+ if (!enabled) return;
111
+ if (window.location.hash) {
112
+ const hashValue = window.location.hash.substring(1);
113
+ const targetElement = document.getElementById(
114
+ `${elementPrefix}${hashValue}`,
115
+ );
116
+ if (targetElement) {
117
+ setTimeout(() => {
118
+ targetElement.scrollIntoView(scrollOptions);
119
+ const container = document.querySelector(containerSelector);
120
+ if (container) {
121
+ container.classList.add(containerActiveClass);
122
+ }
123
+ const allElements = document.querySelectorAll(elementSelector);
124
+ targetElement.classList.add(highlightClass);
125
+ allElements.forEach((element) => {
126
+ if (element !== targetElement) {
127
+ element.classList.add(blurClass);
128
+ }
129
+ });
130
+ const overlay = document.createElement("div");
131
+ overlay.className = "hash-nav-overlay";
132
+ document.body.appendChild(overlay);
133
+ let effectTimeoutId = null;
134
+ const removeEffects = () => {
135
+ if (effectTimeoutId) {
136
+ clearTimeout(effectTimeoutId);
137
+ effectTimeoutId = null;
138
+ }
139
+ allElements.forEach((element) => {
140
+ element.classList.remove(blurClass);
141
+ });
142
+ targetElement.classList.remove(highlightClass);
143
+ if (container) {
144
+ container.classList.remove(containerActiveClass);
145
+ }
146
+ if (overlay && overlay.parentNode) {
147
+ overlay.parentNode.removeChild(overlay);
148
+ }
149
+ overlay.removeEventListener("click", removeEffects);
150
+ overlay.removeEventListener("touchstart", removeEffects);
151
+ document.removeEventListener("keydown", handleKeyDown);
152
+ };
153
+ const handleKeyDown = (e) => {
154
+ if (e.key === "Escape") {
155
+ removeEffects();
156
+ }
157
+ };
158
+ overlay.addEventListener("click", removeEffects);
159
+ overlay.addEventListener("touchstart", removeEffects);
160
+ document.addEventListener("keydown", handleKeyDown);
161
+ effectTimeoutId = setTimeout(removeEffects, effectDuration);
162
+ }, scrollDelay);
163
+ }
164
+ }
165
+ return () => {
166
+ const container = document.querySelector(containerSelector);
167
+ const overlay = document.querySelector(".hash-nav-overlay");
168
+ if (container) {
169
+ container.classList.remove(containerActiveClass);
170
+ }
171
+ if (overlay && overlay.parentNode) {
172
+ overlay.parentNode.removeChild(overlay);
173
+ }
174
+ };
175
+ }, [
176
+ enabled,
177
+ elementPrefix,
178
+ elementSelector,
179
+ containerSelector,
180
+ effectDuration,
181
+ scrollDelay,
182
+ scrollOptions,
183
+ ]);
184
+ return null;
185
+ }
@@ -0,0 +1,65 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useLocation } from "@docusaurus/router";
3
+ import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
4
+ export default function UpdateTitle({
5
+ sections = {},
6
+ defaultTitle = null,
7
+ enabled = true,
8
+ }) {
9
+ const location = useLocation();
10
+ const { siteConfig } = useDocusaurusContext();
11
+ const [currentTitle, setCurrentTitle] = useState(null);
12
+ const effectiveDefaultTitle = defaultTitle || siteConfig.title;
13
+ useEffect(() => {
14
+ if (!enabled) return;
15
+ const sectionTitles = Object.keys(sections).length > 0 ? sections : {};
16
+ const updateTitle = () => {
17
+ const sectionsToTrack = Object.keys(sectionTitles)
18
+ .map((id) => document.getElementById(id))
19
+ .filter(Boolean);
20
+ if (sectionsToTrack.length === 0) {
21
+ setCurrentTitle(effectiveDefaultTitle);
22
+ return;
23
+ }
24
+ const viewportHeight = window.innerHeight;
25
+ let maxVisibleSection = null;
26
+ let maxVisibleArea = 0;
27
+ sectionsToTrack.forEach((section) => {
28
+ const rect = section.getBoundingClientRect();
29
+ const visibleTop = Math.max(0, rect.top);
30
+ const visibleBottom = Math.min(viewportHeight, rect.bottom);
31
+ const visibleArea = Math.max(0, visibleBottom - visibleTop);
32
+ if (visibleArea > maxVisibleArea) {
33
+ maxVisibleArea = visibleArea;
34
+ maxVisibleSection = section.id;
35
+ }
36
+ });
37
+ if (maxVisibleSection && sectionTitles[maxVisibleSection]) {
38
+ setCurrentTitle(sectionTitles[maxVisibleSection]);
39
+ } else {
40
+ setCurrentTitle(effectiveDefaultTitle);
41
+ }
42
+ };
43
+ let isScrolling = false;
44
+ const handleScroll = () => {
45
+ if (!isScrolling) {
46
+ window.requestAnimationFrame(() => {
47
+ updateTitle();
48
+ isScrolling = false;
49
+ });
50
+ isScrolling = true;
51
+ }
52
+ };
53
+ window.addEventListener("scroll", handleScroll);
54
+ updateTitle();
55
+ return () => {
56
+ window.removeEventListener("scroll", handleScroll);
57
+ };
58
+ }, [location.pathname, sections, effectiveDefaultTitle, enabled]);
59
+ useEffect(() => {
60
+ if (currentTitle) {
61
+ document.title = currentTitle;
62
+ }
63
+ }, [currentTitle]);
64
+ return null;
65
+ }